| ... | @@ -63,11 +63,13 @@ globals_free_list: std.ArrayListUnmanaged(u32) = .{}, | ... | @@ -63,11 +63,13 @@ globals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 63 | strtab: StringTable(.strtab) = .{}, | 63 | strtab: StringTable(.strtab) = .{}, |
| 64 | strtab_offset: ?u32 = null, | 64 | strtab_offset: ?u32 = null, |
| 65 | | 65 | |
| 66 | got_entries: std.AutoArrayHashMapUnmanaged(SymbolWithLoc, u32) = .{}, | 66 | got_entries: std.ArrayListUnmanaged(Entry) = .{}, |
| 67 | got_entries_free_list: std.ArrayListUnmanaged(u32) = .{}, | 67 | got_entries_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| | 68 | got_entries_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, |
| 68 | | 69 | |
| 69 | imports_table: std.AutoArrayHashMapUnmanaged(SymbolWithLoc, u32) = .{}, | 70 | imports: std.ArrayListUnmanaged(Entry) = .{}, |
| 70 | imports_table_free_list: std.ArrayListUnmanaged(u32) = .{}, | 71 | imports_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| | 72 | imports_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{}, |
| 71 | | 73 | |
| 72 | /// Virtual address of the entry point procedure relative to image base. | 74 | /// Virtual address of the entry point procedure relative to image base. |
| 73 | entry_addr: ?u32 = null, | 75 | entry_addr: ?u32 = null, |
| ... | @@ -115,6 +117,12 @@ relocs: RelocTable = .{}, | ... | @@ -115,6 +117,12 @@ relocs: RelocTable = .{}, |
| 115 | /// this will be a table indexed by index into the list of Atoms. | 117 | /// this will be a table indexed by index into the list of Atoms. |
| 116 | base_relocs: BaseRelocationTable = .{}, | 118 | base_relocs: BaseRelocationTable = .{}, |
| 117 | | 119 | |
| | 120 | const Entry = struct { |
| | 121 | target: SymbolWithLoc, |
| | 122 | // Index into the synthetic symbol table (i.e., file == null). |
| | 123 | sym_index: u32, |
| | 124 | }; |
| | 125 | |
| 118 | pub const Reloc = struct { | 126 | pub const Reloc = struct { |
| 119 | @"type": enum { | 127 | @"type": enum { |
| 120 | got, | 128 | got, |
| ... | @@ -309,8 +317,10 @@ pub fn deinit(self: *Coff) void { | ... | @@ -309,8 +317,10 @@ pub fn deinit(self: *Coff) void { |
| 309 | self.strtab.deinit(gpa); | 317 | self.strtab.deinit(gpa); |
| 310 | self.got_entries.deinit(gpa); | 318 | self.got_entries.deinit(gpa); |
| 311 | self.got_entries_free_list.deinit(gpa); | 319 | self.got_entries_free_list.deinit(gpa); |
| | 320 | self.got_entries_table.deinit(gpa); |
| | 321 | self.imports.deinit(gpa); |
| | 322 | self.imports_free_list.deinit(gpa); |
| 312 | self.imports_table.deinit(gpa); | 323 | self.imports_table.deinit(gpa); |
| 313 | self.imports_table_free_list.deinit(gpa); | | |
| 314 | self.decls.deinit(gpa); | 324 | self.decls.deinit(gpa); |
| 315 | self.atom_by_index_table.deinit(gpa); | 325 | self.atom_by_index_table.deinit(gpa); |
| 316 | | 326 | |
| ... | @@ -684,42 +694,44 @@ fn allocateGlobal(self: *Coff) !u32 { | ... | @@ -684,42 +694,44 @@ fn allocateGlobal(self: *Coff) !u32 { |
| 684 | pub fn allocateGotEntry(self: *Coff, target: SymbolWithLoc) !u32 { | 694 | pub fn allocateGotEntry(self: *Coff, target: SymbolWithLoc) !u32 { |
| 685 | const gpa = self.base.allocator; | 695 | const gpa = self.base.allocator; |
| 686 | try self.got_entries.ensureUnusedCapacity(gpa, 1); | 696 | try self.got_entries.ensureUnusedCapacity(gpa, 1); |
| | 697 | |
| 687 | const index: u32 = blk: { | 698 | const index: u32 = blk: { |
| 688 | if (self.got_entries_free_list.popOrNull()) |index| { | 699 | if (self.got_entries_free_list.popOrNull()) |index| { |
| 689 | log.debug(" (reusing GOT entry index {d})", .{index}); | 700 | log.debug(" (reusing GOT entry index {d})", .{index}); |
| 690 | if (self.got_entries.getIndex(target)) |existing| { | | |
| 691 | assert(existing == index); | | |
| 692 | } | | |
| 693 | break :blk index; | 701 | break :blk index; |
| 694 | } else { | 702 | } else { |
| 695 | log.debug(" (allocating GOT entry at index {d})", .{self.got_entries.keys().len}); | 703 | log.debug(" (allocating GOT entry at index {d})", .{self.got_entries.items.len}); |
| 696 | const index = @intCast(u32, self.got_entries.keys().len); | 704 | const index = @intCast(u32, self.got_entries.items.len); |
| 697 | self.got_entries.putAssumeCapacityNoClobber(target, 0); | 705 | _ = self.got_entries.addOneAssumeCapacity(); |
| 698 | break :blk index; | 706 | break :blk index; |
| 699 | } | 707 | } |
| 700 | }; | 708 | }; |
| 701 | self.got_entries.keys()[index] = target; | 709 | |
| | 710 | self.got_entries.items[index] = .{ .target = target, .sym_index = 0 }; |
| | 711 | try self.got_entries_table.putNoClobber(gpa, target, index); |
| | 712 | |
| 702 | return index; | 713 | return index; |
| 703 | } | 714 | } |
| 704 | | 715 | |
| 705 | pub fn allocateImportEntry(self: *Coff, target: SymbolWithLoc) !u32 { | 716 | pub fn allocateImportEntry(self: *Coff, target: SymbolWithLoc) !u32 { |
| 706 | const gpa = self.base.allocator; | 717 | const gpa = self.base.allocator; |
| 707 | try self.imports_table.ensureUnusedCapacity(gpa, 1); | 718 | try self.imports.ensureUnusedCapacity(gpa, 1); |
| | 719 | |
| 708 | const index: u32 = blk: { | 720 | const index: u32 = blk: { |
| 709 | if (self.imports_table_free_list.popOrNull()) |index| { | 721 | if (self.imports_free_list.popOrNull()) |index| { |
| 710 | log.debug(" (reusing import entry index {d})", .{index}); | 722 | log.debug(" (reusing import entry index {d})", .{index}); |
| 711 | if (self.imports_table.getIndex(target)) |existing| { | | |
| 712 | assert(existing == index); | | |
| 713 | } | | |
| 714 | break :blk index; | 723 | break :blk index; |
| 715 | } else { | 724 | } else { |
| 716 | log.debug(" (allocating import entry at index {d})", .{self.imports_table.keys().len}); | 725 | log.debug(" (allocating import entry at index {d})", .{self.imports.items.len}); |
| 717 | const index = @intCast(u32, self.imports_table.keys().len); | 726 | const index = @intCast(u32, self.imports.items.len); |
| 718 | self.imports_table.putAssumeCapacityNoClobber(target, 0); | 727 | _ = self.imports.addOneAssumeCapacity(); |
| 719 | break :blk index; | 728 | break :blk index; |
| 720 | } | 729 | } |
| 721 | }; | 730 | }; |
| 722 | self.imports_table.keys()[index] = target; | 731 | |
| | 732 | self.imports.items[index] = .{ .target = target, .sym_index = 0 }; |
| | 733 | try self.imports_table.putNoClobber(gpa, target, index); |
| | 734 | |
| 723 | return index; | 735 | return index; |
| 724 | } | 736 | } |
| 725 | | 737 | |
| ... | @@ -734,7 +746,6 @@ fn createGotAtom(self: *Coff, target: SymbolWithLoc) !*Atom { | ... | @@ -734,7 +746,6 @@ fn createGotAtom(self: *Coff, target: SymbolWithLoc) !*Atom { |
| 734 | | 746 | |
| 735 | try self.managed_atoms.append(gpa, atom); | 747 | try self.managed_atoms.append(gpa, atom); |
| 736 | try self.atom_by_index_table.putNoClobber(gpa, atom.sym_index, atom); | 748 | try self.atom_by_index_table.putNoClobber(gpa, atom.sym_index, atom); |
| 737 | self.got_entries.getPtr(target).?.* = atom.sym_index; | | |
| 738 | | 749 | |
| 739 | const sym = atom.getSymbolPtr(self); | 750 | const sym = atom.getSymbolPtr(self); |
| 740 | sym.section_number = @intToEnum(coff.SectionNumber, self.got_section_index.? + 1); | 751 | sym.section_number = @intToEnum(coff.SectionNumber, self.got_section_index.? + 1); |
| ... | @@ -762,7 +773,7 @@ fn createGotAtom(self: *Coff, target: SymbolWithLoc) !*Atom { | ... | @@ -762,7 +773,7 @@ fn createGotAtom(self: *Coff, target: SymbolWithLoc) !*Atom { |
| 762 | return atom; | 773 | return atom; |
| 763 | } | 774 | } |
| 764 | | 775 | |
| 765 | fn createImportAtom(self: *Coff, target: SymbolWithLoc) !*Atom { | 776 | fn createImportAtom(self: *Coff) !*Atom { |
| 766 | const gpa = self.base.allocator; | 777 | const gpa = self.base.allocator; |
| 767 | const atom = try gpa.create(Atom); | 778 | const atom = try gpa.create(Atom); |
| 768 | errdefer gpa.destroy(atom); | 779 | errdefer gpa.destroy(atom); |
| ... | @@ -773,7 +784,6 @@ fn createImportAtom(self: *Coff, target: SymbolWithLoc) !*Atom { | ... | @@ -773,7 +784,6 @@ fn createImportAtom(self: *Coff, target: SymbolWithLoc) !*Atom { |
| 773 | | 784 | |
| 774 | try self.managed_atoms.append(gpa, atom); | 785 | try self.managed_atoms.append(gpa, atom); |
| 775 | try self.atom_by_index_table.putNoClobber(gpa, atom.sym_index, atom); | 786 | try self.atom_by_index_table.putNoClobber(gpa, atom.sym_index, atom); |
| 776 | self.imports_table.getPtr(target).?.* = atom.sym_index; | | |
| 777 | | 787 | |
| 778 | const sym = atom.getSymbolPtr(self); | 788 | const sym = atom.getSymbolPtr(self); |
| 779 | sym.section_number = @intToEnum(coff.SectionNumber, self.idata_section_index.? + 1); | 789 | sym.section_number = @intToEnum(coff.SectionNumber, self.idata_section_index.? + 1); |
| ... | @@ -804,7 +814,7 @@ fn writeAtom(self: *Coff, atom: *Atom, code: []const u8) !void { | ... | @@ -804,7 +814,7 @@ fn writeAtom(self: *Coff, atom: *Atom, code: []const u8) !void { |
| 804 | const sym = atom.getSymbol(self); | 814 | const sym = atom.getSymbol(self); |
| 805 | const section = self.sections.get(@enumToInt(sym.section_number) - 1); | 815 | const section = self.sections.get(@enumToInt(sym.section_number) - 1); |
| 806 | const file_offset = section.header.pointer_to_raw_data + sym.value - section.header.virtual_address; | 816 | const file_offset = section.header.pointer_to_raw_data + sym.value - section.header.virtual_address; |
| 807 | log.debug("writing atom for symbol {s} at file offset 0x{x}", .{ atom.getName(self), file_offset }); | 817 | log.debug("writing atom for symbol {s} at file offset 0x{x} to 0x{x}", .{ atom.getName(self), file_offset, file_offset + code.len }); |
| 808 | try self.base.file.?.pwriteAll(code, file_offset); | 818 | try self.base.file.?.pwriteAll(code, file_offset); |
| 809 | try self.resolveRelocs(atom); | 819 | try self.resolveRelocs(atom); |
| 810 | } | 820 | } |
| ... | @@ -860,11 +870,12 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void { | ... | @@ -860,11 +870,12 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void { |
| 860 | const target_vaddr = target_atom.getSymbol(self).value; | 870 | const target_vaddr = target_atom.getSymbol(self).value; |
| 861 | const target_vaddr_with_addend = target_vaddr + reloc.addend; | 871 | const target_vaddr_with_addend = target_vaddr + reloc.addend; |
| 862 | | 872 | |
| 863 | log.debug(" ({x}: [() => 0x{x} ({s})) ({s})", .{ | 873 | log.debug(" ({x}: [() => 0x{x} ({s})) ({s}) (in file at 0x{x})", .{ |
| 864 | source_sym.value + reloc.offset, | 874 | source_sym.value + reloc.offset, |
| 865 | target_vaddr_with_addend, | 875 | target_vaddr_with_addend, |
| 866 | self.getSymbolName(reloc.target), | 876 | self.getSymbolName(reloc.target), |
| 867 | @tagName(reloc.@"type"), | 877 | @tagName(reloc.@"type"), |
| | 878 | file_offset + reloc.offset, |
| 868 | }); | 879 | }); |
| 869 | | 880 | |
| 870 | reloc.dirty = false; | 881 | reloc.dirty = false; |
| ... | @@ -901,8 +912,7 @@ fn freeAtom(self: *Coff, atom: *Atom) void { | ... | @@ -901,8 +912,7 @@ fn freeAtom(self: *Coff, atom: *Atom) void { |
| 901 | log.debug("freeAtom {*}", .{atom}); | 912 | log.debug("freeAtom {*}", .{atom}); |
| 902 | | 913 | |
| 903 | // Remove any relocs and base relocs associated with this Atom | 914 | // Remove any relocs and base relocs associated with this Atom |
| 904 | _ = self.relocs.remove(atom); | 915 | self.freeRelocationsForAtom(atom); |
| 905 | _ = self.base_relocs.remove(atom); | | |
| 906 | | 916 | |
| 907 | const sym = atom.getSymbol(self); | 917 | const sym = atom.getSymbol(self); |
| 908 | const sect_id = @enumToInt(sym.section_number) - 1; | 918 | const sect_id = @enumToInt(sym.section_number) - 1; |
| ... | @@ -966,11 +976,14 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live | ... | @@ -966,11 +976,14 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live |
| 966 | const tracy = trace(@src()); | 976 | const tracy = trace(@src()); |
| 967 | defer tracy.end(); | 977 | defer tracy.end(); |
| 968 | | 978 | |
| | 979 | const decl_index = func.owner_decl; |
| | 980 | const decl = module.declPtr(decl_index); |
| | 981 | self.freeUnnamedConsts(decl_index); |
| | 982 | self.freeRelocationsForAtom(&decl.link.coff); |
| | 983 | |
| 969 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); | 984 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 970 | defer code_buffer.deinit(); | 985 | defer code_buffer.deinit(); |
| 971 | | 986 | |
| 972 | const decl_index = func.owner_decl; | | |
| 973 | const decl = module.declPtr(decl_index); | | |
| 974 | const res = try codegen.generateFunction( | 987 | const res = try codegen.generateFunction( |
| 975 | &self.base, | 988 | &self.base, |
| 976 | decl.srcLoc(), | 989 | decl.srcLoc(), |
| ... | @@ -1082,6 +1095,8 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! | ... | @@ -1082,6 +1095,8 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! |
| 1082 | } | 1095 | } |
| 1083 | } | 1096 | } |
| 1084 | | 1097 | |
| | 1098 | self.freeRelocationsForAtom(&decl.link.coff); |
| | 1099 | |
| 1085 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); | 1100 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 1086 | defer code_buffer.deinit(); | 1101 | defer code_buffer.deinit(); |
| 1087 | | 1102 | |
| ... | @@ -1190,8 +1205,9 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, | ... | @@ -1190,8 +1205,9 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, |
| 1190 | sym.value = vaddr; | 1205 | sym.value = vaddr; |
| 1191 | | 1206 | |
| 1192 | const got_target = SymbolWithLoc{ .sym_index = atom.sym_index, .file = null }; | 1207 | const got_target = SymbolWithLoc{ .sym_index = atom.sym_index, .file = null }; |
| 1193 | _ = try self.allocateGotEntry(got_target); | 1208 | const got_index = try self.allocateGotEntry(got_target); |
| 1194 | const got_atom = try self.createGotAtom(got_target); | 1209 | const got_atom = try self.createGotAtom(got_target); |
| | 1210 | self.got_entries.items[got_index].sym_index = got_atom.sym_index; |
| 1195 | try self.writePtrWidthAtom(got_atom); | 1211 | try self.writePtrWidthAtom(got_atom); |
| 1196 | } | 1212 | } |
| 1197 | | 1213 | |
| ... | @@ -1199,6 +1215,11 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, | ... | @@ -1199,6 +1215,11 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, |
| 1199 | try self.writeAtom(atom, code); | 1215 | try self.writeAtom(atom, code); |
| 1200 | } | 1216 | } |
| 1201 | | 1217 | |
| | 1218 | fn freeRelocationsForAtom(self: *Coff, atom: *Atom) void { |
| | 1219 | _ = self.relocs.remove(atom); |
| | 1220 | _ = self.base_relocs.remove(atom); |
| | 1221 | } |
| | 1222 | |
| 1202 | fn freeUnnamedConsts(self: *Coff, decl_index: Module.Decl.Index) void { | 1223 | fn freeUnnamedConsts(self: *Coff, decl_index: Module.Decl.Index) void { |
| 1203 | const gpa = self.base.allocator; | 1224 | const gpa = self.base.allocator; |
| 1204 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return; | 1225 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return; |
| ... | @@ -1237,14 +1258,20 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { | ... | @@ -1237,14 +1258,20 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { |
| 1237 | | 1258 | |
| 1238 | // Try freeing GOT atom if this decl had one | 1259 | // Try freeing GOT atom if this decl had one |
| 1239 | const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 1260 | const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 1240 | if (self.got_entries.getIndex(got_target)) |got_index| { | 1261 | if (self.got_entries_table.get(got_target)) |got_index| { |
| 1241 | self.got_entries_free_list.append(gpa, @intCast(u32, got_index)) catch {}; | 1262 | self.got_entries_free_list.append(gpa, @intCast(u32, got_index)) catch {}; |
| 1242 | self.got_entries.values()[got_index] = 0; | 1263 | self.got_entries.items[got_index] = .{ |
| | 1264 | .target = .{ .sym_index = 0, .file = null }, |
| | 1265 | .sym_index = 0, |
| | 1266 | }; |
| | 1267 | _ = self.got_entries_table.remove(got_target); |
| | 1268 | |
| 1243 | log.debug(" adding GOT index {d} to free list (target local@{d})", .{ got_index, sym_index }); | 1269 | log.debug(" adding GOT index {d} to free list (target local@{d})", .{ got_index, sym_index }); |
| 1244 | } | 1270 | } |
| 1245 | | 1271 | |
| 1246 | self.locals.items[sym_index].section_number = .UNDEFINED; | 1272 | self.locals.items[sym_index].section_number = .UNDEFINED; |
| 1247 | _ = self.atom_by_index_table.remove(sym_index); | 1273 | _ = self.atom_by_index_table.remove(sym_index); |
| | 1274 | log.debug(" adding local symbol index {d} to free list", .{sym_index}); |
| 1248 | decl.link.coff.sym_index = 0; | 1275 | decl.link.coff.sym_index = 0; |
| 1249 | } | 1276 | } |
| 1250 | } | 1277 | } |
| ... | @@ -1453,8 +1480,9 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -1453,8 +1480,9 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 1453 | const global = self.globals.items[entry.key]; | 1480 | const global = self.globals.items[entry.key]; |
| 1454 | if (self.imports_table.contains(global)) continue; | 1481 | if (self.imports_table.contains(global)) continue; |
| 1455 | | 1482 | |
| 1456 | _ = try self.allocateImportEntry(global); | 1483 | const import_index = try self.allocateImportEntry(global); |
| 1457 | const import_atom = try self.createImportAtom(global); | 1484 | const import_atom = try self.createImportAtom(); |
| | 1485 | self.imports.items[import_index].sym_index = import_atom.sym_index; |
| 1458 | try self.writePtrWidthAtom(import_atom); | 1486 | try self.writePtrWidthAtom(import_atom); |
| 1459 | } | 1487 | } |
| 1460 | | 1488 | |
| ... | @@ -1668,8 +1696,8 @@ fn writeImportTable(self: *Coff) !void { | ... | @@ -1668,8 +1696,8 @@ fn writeImportTable(self: *Coff) !void { |
| 1668 | defer names_table.deinit(); | 1696 | defer names_table.deinit(); |
| 1669 | | 1697 | |
| 1670 | // TODO: check if import is still valid | 1698 | // TODO: check if import is still valid |
| 1671 | for (self.imports_table.keys()) |target| { | 1699 | for (self.imports.items) |entry| { |
| 1672 | const target_name = self.getSymbolName(target); | 1700 | const target_name = self.getSymbolName(entry.target); |
| 1673 | const start = names_table.items.len; | 1701 | const start = names_table.items.len; |
| 1674 | mem.writeIntLittle(u16, try names_table.addManyAsArray(2), 0); // TODO: currently, hint is set to 0 as we haven't yet parsed any DLL | 1702 | mem.writeIntLittle(u16, try names_table.addManyAsArray(2), 0); // TODO: currently, hint is set to 0 as we haven't yet parsed any DLL |
| 1675 | try names_table.appendSlice(target_name); | 1703 | try names_table.appendSlice(target_name); |
| ... | @@ -2013,19 +2041,19 @@ pub fn getEntryPoint(self: Coff) ?SymbolWithLoc { | ... | @@ -2013,19 +2041,19 @@ pub fn getEntryPoint(self: Coff) ?SymbolWithLoc { |
| 2013 | return self.globals.items[global_index]; | 2041 | return self.globals.items[global_index]; |
| 2014 | } | 2042 | } |
| 2015 | | 2043 | |
| 2016 | /// Returns pointer-to-symbol described by `sym_with_loc` descriptor. | 2044 | /// Returns pointer-to-symbol described by `sym_loc` descriptor. |
| 2017 | pub fn getSymbolPtr(self: *Coff, sym_loc: SymbolWithLoc) *coff.Symbol { | 2045 | pub fn getSymbolPtr(self: *Coff, sym_loc: SymbolWithLoc) *coff.Symbol { |
| 2018 | assert(sym_loc.file == null); // TODO linking object files | 2046 | assert(sym_loc.file == null); // TODO linking object files |
| 2019 | return &self.locals.items[sym_loc.sym_index]; | 2047 | return &self.locals.items[sym_loc.sym_index]; |
| 2020 | } | 2048 | } |
| 2021 | | 2049 | |
| 2022 | /// Returns symbol described by `sym_with_loc` descriptor. | 2050 | /// Returns symbol described by `sym_loc` descriptor. |
| 2023 | pub fn getSymbol(self: *const Coff, sym_loc: SymbolWithLoc) *const coff.Symbol { | 2051 | pub fn getSymbol(self: *const Coff, sym_loc: SymbolWithLoc) *const coff.Symbol { |
| 2024 | assert(sym_loc.file == null); // TODO linking object files | 2052 | assert(sym_loc.file == null); // TODO linking object files |
| 2025 | return &self.locals.items[sym_loc.sym_index]; | 2053 | return &self.locals.items[sym_loc.sym_index]; |
| 2026 | } | 2054 | } |
| 2027 | | 2055 | |
| 2028 | /// Returns name of the symbol described by `sym_with_loc` descriptor. | 2056 | /// Returns name of the symbol described by `sym_loc` descriptor. |
| 2029 | pub fn getSymbolName(self: *const Coff, sym_loc: SymbolWithLoc) []const u8 { | 2057 | pub fn getSymbolName(self: *const Coff, sym_loc: SymbolWithLoc) []const u8 { |
| 2030 | assert(sym_loc.file == null); // TODO linking object files | 2058 | assert(sym_loc.file == null); // TODO linking object files |
| 2031 | const sym = self.getSymbol(sym_loc); | 2059 | const sym = self.getSymbol(sym_loc); |
| ... | @@ -2033,25 +2061,27 @@ pub fn getSymbolName(self: *const Coff, sym_loc: SymbolWithLoc) []const u8 { | ... | @@ -2033,25 +2061,27 @@ pub fn getSymbolName(self: *const Coff, sym_loc: SymbolWithLoc) []const u8 { |
| 2033 | return self.strtab.get(offset).?; | 2061 | return self.strtab.get(offset).?; |
| 2034 | } | 2062 | } |
| 2035 | | 2063 | |
| 2036 | /// Returns atom if there is an atom referenced by the symbol described by `sym_with_loc` descriptor. | 2064 | /// Returns atom if there is an atom referenced by the symbol described by `sym_loc` descriptor. |
| 2037 | /// Returns null on failure. | 2065 | /// Returns null on failure. |
| 2038 | pub fn getAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { | 2066 | pub fn getAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { |
| 2039 | assert(sym_loc.file == null); // TODO linking with object files | 2067 | assert(sym_loc.file == null); // TODO linking with object files |
| 2040 | return self.atom_by_index_table.get(sym_loc.sym_index); | 2068 | return self.atom_by_index_table.get(sym_loc.sym_index); |
| 2041 | } | 2069 | } |
| 2042 | | 2070 | |
| 2043 | /// Returns GOT atom that references `sym_with_loc` if one exists. | 2071 | /// Returns GOT atom that references `sym_loc` if one exists. |
| 2044 | /// Returns null otherwise. | 2072 | /// Returns null otherwise. |
| 2045 | pub fn getGotAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { | 2073 | pub fn getGotAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { |
| 2046 | const got_index = self.got_entries.get(sym_loc) orelse return null; | 2074 | const got_index = self.got_entries_table.get(sym_loc) orelse return null; |
| 2047 | return self.atom_by_index_table.get(got_index); | 2075 | const got_entry = self.got_entries.items[got_index]; |
| | 2076 | return self.getAtomForSymbol(.{ .sym_index = got_entry.sym_index, .file = null }); |
| 2048 | } | 2077 | } |
| 2049 | | 2078 | |
| 2050 | /// Returns import atom that references `sym_with_loc` if one exists. | 2079 | /// Returns import atom that references `sym_loc` if one exists. |
| 2051 | /// Returns null otherwise. | 2080 | /// Returns null otherwise. |
| 2052 | pub fn getImportAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { | 2081 | pub fn getImportAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { |
| 2053 | const imports_index = self.imports_table.get(sym_loc) orelse return null; | 2082 | const imports_index = self.imports_table.get(sym_loc) orelse return null; |
| 2054 | return self.atom_by_index_table.get(imports_index); | 2083 | const imports_entry = self.imports.items[imports_index]; |
| | 2084 | return self.getAtomForSymbol(.{ .sym_index = imports_entry.sym_index, .file = null }); |
| 2055 | } | 2085 | } |
| 2056 | | 2086 | |
| 2057 | fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !void { | 2087 | fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !void { |
| ... | @@ -2141,21 +2171,21 @@ fn logSymtab(self: *Coff) void { | ... | @@ -2141,21 +2171,21 @@ fn logSymtab(self: *Coff) void { |
| 2141 | } | 2171 | } |
| 2142 | | 2172 | |
| 2143 | log.debug("GOT entries:", .{}); | 2173 | log.debug("GOT entries:", .{}); |
| 2144 | for (self.got_entries.keys()) |target, i| { | 2174 | for (self.got_entries.items) |entry, i| { |
| 2145 | const got_sym = self.getSymbol(.{ .sym_index = self.got_entries.values()[i], .file = null }); | 2175 | const got_sym = self.getSymbol(.{ .sym_index = entry.sym_index, .file = null }); |
| 2146 | const target_sym = self.getSymbol(target); | 2176 | const target_sym = self.getSymbol(entry.target); |
| 2147 | if (target_sym.section_number == .UNDEFINED) { | 2177 | if (target_sym.section_number == .UNDEFINED) { |
| 2148 | log.debug(" {d}@{x} => import('{s}')", .{ | 2178 | log.debug(" {d}@{x} => import('{s}')", .{ |
| 2149 | i, | 2179 | i, |
| 2150 | got_sym.value, | 2180 | got_sym.value, |
| 2151 | self.getSymbolName(target), | 2181 | self.getSymbolName(entry.target), |
| 2152 | }); | 2182 | }); |
| 2153 | } else { | 2183 | } else { |
| 2154 | log.debug(" {d}@{x} => local(%{d}) in object({?d}) {s}", .{ | 2184 | log.debug(" {d}@{x} => local(%{d}) in object({?d}) {s}", .{ |
| 2155 | i, | 2185 | i, |
| 2156 | got_sym.value, | 2186 | got_sym.value, |
| 2157 | target.sym_index, | 2187 | entry.target.sym_index, |
| 2158 | target.file, | 2188 | entry.target.file, |
| 2159 | logSymAttributes(target_sym, &buf), | 2189 | logSymAttributes(target_sym, &buf), |
| 2160 | }); | 2190 | }); |
| 2161 | } | 2191 | } |