| ... | @@ -30,6 +30,7 @@ lib_string_len: u64, | ... | @@ -30,6 +30,7 @@ lib_string_len: u64, |
| 30 | long_names_table: LongNamesTable, | 30 | long_names_table: LongNamesTable, |
| 31 | import_table: ImportTable, | 31 | import_table: ImportTable, |
| 32 | export_table: ExportTable, | 32 | export_table: ExportTable, |
| | 33 | symbol_table: SymbolTable, |
| 33 | strings: std.HashMapUnmanaged( | 34 | strings: std.HashMapUnmanaged( |
| 34 | u32, | 35 | u32, |
| 35 | void, | 36 | void, |
| ... | @@ -37,10 +38,10 @@ strings: std.HashMapUnmanaged( | ... | @@ -37,10 +38,10 @@ strings: std.HashMapUnmanaged( |
| 37 | std.hash_map.default_max_load_percentage, | 38 | std.hash_map.default_max_load_percentage, |
| 38 | ), | 39 | ), |
| 39 | string_bytes: std.ArrayList(u8), | 40 | string_bytes: std.ArrayList(u8), |
| 40 | image_section_table: std.ArrayList(Symbol.Index), | 41 | section_table: std.ArrayList(Symbol.Index), |
| 41 | pseudo_section_table: std.array_hash_map.Auto(String, Symbol.Index), | 42 | pseudo_section_table: std.array_hash_map.Auto(String, Symbol.Index), |
| 42 | object_section_table: std.array_hash_map.Auto(String, Symbol.Index), | 43 | object_section_table: std.array_hash_map.Auto(String, Symbol.Index), |
| 43 | symbol_table: std.ArrayList(Symbol), | 44 | symbols: std.ArrayList(Symbol), |
| 44 | globals: std.array_hash_map.Auto(GlobalName, Symbol.Index), | 45 | globals: std.array_hash_map.Auto(GlobalName, Symbol.Index), |
| 45 | global_pending_index: u32, | 46 | global_pending_index: u32, |
| 46 | navs: std.array_hash_map.Auto(InternPool.Nav.Index, Symbol.Index), | 47 | navs: std.array_hash_map.Auto(InternPool.Nav.Index, Symbol.Index), |
| ... | @@ -144,6 +145,7 @@ pub const Node = union(enum) { | ... | @@ -144,6 +145,7 @@ pub const Node = union(enum) { |
| 144 | header, | 145 | header, |
| 145 | /// Images and archives only. | 146 | /// Images and archives only. |
| 146 | signature, | 147 | signature, |
| | 148 | |
| 147 | /// Archives only. | 149 | /// Archives only. |
| 148 | archive_member_header: Member.Index, | 150 | archive_member_header: Member.Index, |
| 149 | archive_member: Member.Index, | 151 | archive_member: Member.Index, |
| ... | @@ -154,15 +156,21 @@ pub const Node = union(enum) { | ... | @@ -154,15 +156,21 @@ pub const Node = union(enum) { |
| 154 | /// Image only | 156 | /// Image only |
| 155 | data_directories, | 157 | data_directories, |
| 156 | section_table, | 158 | section_table, |
| 157 | image_section: Symbol.Index, | 159 | // Archives and objects only |
| | 160 | symbol_table, |
| | 161 | symbol_table_entry, |
| | 162 | // Archives and objects only |
| | 163 | string_table, |
| | 164 | |
| | 165 | image_section: Symbol.Index, // TODO: image_section -> section |
| 158 | | 166 | |
| 159 | /// Only images contain imports | 167 | /// Images only |
| 160 | import_directory_table, | 168 | import_directory_table, |
| 161 | import_lookup_table: ImportTable.Index, | 169 | import_lookup_table: ImportTable.Index, |
| 162 | import_address_table: ImportTable.Index, | 170 | import_address_table: ImportTable.Index, |
| 163 | import_hint_name_table: ImportTable.Index, | 171 | import_hint_name_table: ImportTable.Index, |
| 164 | | 172 | |
| 165 | /// Only images contain exports | 173 | /// Images only |
| 166 | export_directory_table, | 174 | export_directory_table, |
| 167 | export_address_table, | 175 | export_address_table, |
| 168 | export_name_pointer_table, | 176 | export_name_pointer_table, |
| ... | @@ -291,6 +299,8 @@ pub const Node = union(enum) { | ... | @@ -291,6 +299,8 @@ pub const Node = union(enum) { |
| 291 | optional_header, | 299 | optional_header, |
| 292 | data_directories, | 300 | data_directories, |
| 293 | section_table, | 301 | section_table, |
| | 302 | symbol_table, |
| | 303 | string_table, |
| 294 | }; | 304 | }; |
| 295 | var mut_known: std.enums.EnumFieldStruct(Known, MappedFile.Node.Index, null) = undefined; | 305 | var mut_known: std.enums.EnumFieldStruct(Known, MappedFile.Node.Index, null) = undefined; |
| 296 | const info = @typeInfo(Known).@"enum"; | 306 | const info = @typeInfo(Known).@"enum"; |
| ... | @@ -436,6 +446,47 @@ pub const LongNamesTable = struct { | ... | @@ -436,6 +446,47 @@ pub const LongNamesTable = struct { |
| 436 | }; | 446 | }; |
| 437 | }; | 447 | }; |
| 438 | | 448 | |
| | 449 | pub const SymbolTable = struct { |
| | 450 | string_offsets: std.AutoArrayHashMapUnmanaged(String, StringIndex), |
| | 451 | entries: std.AutoArrayHashMapUnmanaged(Symbol.Index, Entry), |
| | 452 | |
| | 453 | // Adding nodes to the symbol table has the result of accumulating padding |
| | 454 | // between the last symbol and the string table, due to the growth factor |
| | 455 | // in MappedFile. The spec requires the string table begin immediately |
| | 456 | // after the last symbol, so we compact the symbol table node if needed. |
| | 457 | pending_shrink: bool, |
| | 458 | |
| | 459 | pub const Entry = struct { |
| | 460 | entry_si: Symbol.Index, |
| | 461 | index: Index, |
| | 462 | }; |
| | 463 | |
| | 464 | pub const Add = union(enum) { |
| | 465 | section, |
| | 466 | global: struct { |
| | 467 | import: bool, |
| | 468 | }, |
| | 469 | }; |
| | 470 | |
| | 471 | pub const SymbolName = union(enum) { |
| | 472 | short: []const u8, |
| | 473 | long: StringIndex, |
| | 474 | }; |
| | 475 | |
| | 476 | // Symbol.Index does not map 1:1 with SymbolTable.Index due to auxiliary entries |
| | 477 | pub const Index = enum(u32) { |
| | 478 | _, |
| | 479 | |
| | 480 | pub fn get(sti: SymbolTable.Index, coff: *Coff) *Entry { |
| | 481 | return &coff.symbol_table.entries.values()[@intFromEnum(sti)]; |
| | 482 | } |
| | 483 | }; |
| | 484 | |
| | 485 | pub const StringIndex = enum(u32) { |
| | 486 | _, |
| | 487 | }; |
| | 488 | }; |
| | 489 | |
| 439 | pub const ExportTable = struct { | 490 | pub const ExportTable = struct { |
| 440 | ni: MappedFile.Node.Index, | 491 | ni: MappedFile.Node.Index, |
| 441 | export_directory_table_ni: MappedFile.Node.Index, | 492 | export_directory_table_ni: MappedFile.Node.Index, |
| ... | @@ -582,7 +633,7 @@ pub const Symbol = struct { | ... | @@ -582,7 +633,7 @@ pub const Symbol = struct { |
| 582 | } | 633 | } |
| 583 | | 634 | |
| 584 | pub fn symbol(sn: SectionNumber, coff: *const Coff) Symbol.Index { | 635 | pub fn symbol(sn: SectionNumber, coff: *const Coff) Symbol.Index { |
| 585 | return coff.image_section_table.items[sn.toIndex()]; | 636 | return coff.section_table.items[sn.toIndex()]; |
| 586 | } | 637 | } |
| 587 | | 638 | |
| 588 | pub fn header(sn: SectionNumber, coff: *Coff) *std.coff.SectionHeader { | 639 | pub fn header(sn: SectionNumber, coff: *Coff) *std.coff.SectionHeader { |
| ... | @@ -600,7 +651,7 @@ pub const Symbol = struct { | ... | @@ -600,7 +651,7 @@ pub const Symbol = struct { |
| 600 | const known_count = @typeInfo(Index).@"enum".field_names.len; | 651 | const known_count = @typeInfo(Index).@"enum".field_names.len; |
| 601 | | 652 | |
| 602 | pub fn get(si: Symbol.Index, coff: *Coff) *Symbol { | 653 | pub fn get(si: Symbol.Index, coff: *Coff) *Symbol { |
| 603 | return &coff.symbol_table.items[@intFromEnum(si)]; | 654 | return &coff.symbols.items[@intFromEnum(si)]; |
| 604 | } | 655 | } |
| 605 | | 656 | |
| 606 | pub fn node(si: Symbol.Index, coff: *Coff) MappedFile.Node.Index { | 657 | pub fn node(si: Symbol.Index, coff: *Coff) MappedFile.Node.Index { |
| ... | @@ -920,12 +971,17 @@ fn create( | ... | @@ -920,12 +971,17 @@ fn create( |
| 920 | .name_table_ni = .none, | 971 | .name_table_ni = .none, |
| 921 | .entries = .empty, | 972 | .entries = .empty, |
| 922 | }, | 973 | }, |
| | 974 | .symbol_table = .{ |
| | 975 | .string_offsets = .empty, |
| | 976 | .entries = .empty, |
| | 977 | .pending_shrink = false, |
| | 978 | }, |
| 923 | .strings = .empty, | 979 | .strings = .empty, |
| 924 | .string_bytes = .empty, | 980 | .string_bytes = .empty, |
| 925 | .image_section_table = .empty, | 981 | .section_table = .empty, |
| 926 | .pseudo_section_table = .empty, | 982 | .pseudo_section_table = .empty, |
| 927 | .object_section_table = .empty, | 983 | .object_section_table = .empty, |
| 928 | .symbol_table = .empty, | 984 | .symbols = .empty, |
| 929 | .globals = .empty, | 985 | .globals = .empty, |
| 930 | .global_pending_index = 0, | 986 | .global_pending_index = 0, |
| 931 | .navs = .empty, | 987 | .navs = .empty, |
| ... | @@ -965,15 +1021,16 @@ pub fn deinit(coff: *Coff) void { | ... | @@ -965,15 +1021,16 @@ pub fn deinit(coff: *Coff) void { |
| 965 | const gpa = coff.base.comp.gpa; | 1021 | const gpa = coff.base.comp.gpa; |
| 966 | coff.mf.deinit(gpa); | 1022 | coff.mf.deinit(gpa); |
| 967 | coff.nodes.deinit(gpa); | 1023 | coff.nodes.deinit(gpa); |
| | 1024 | // TODO: Update this |
| 968 | coff.long_names_table.entries.deinit(gpa); | 1025 | coff.long_names_table.entries.deinit(gpa); |
| 969 | coff.import_table.entries.deinit(gpa); | 1026 | coff.import_table.entries.deinit(gpa); |
| 970 | coff.export_table.entries.deinit(gpa); | 1027 | coff.export_table.entries.deinit(gpa); |
| 971 | coff.strings.deinit(gpa); | 1028 | coff.strings.deinit(gpa); |
| 972 | coff.string_bytes.deinit(gpa); | 1029 | coff.string_bytes.deinit(gpa); |
| 973 | coff.image_section_table.deinit(gpa); | 1030 | coff.section_table.deinit(gpa); |
| 974 | coff.pseudo_section_table.deinit(gpa); | 1031 | coff.pseudo_section_table.deinit(gpa); |
| 975 | coff.object_section_table.deinit(gpa); | 1032 | coff.object_section_table.deinit(gpa); |
| 976 | coff.symbol_table.deinit(gpa); | 1033 | coff.symbols.deinit(gpa); |
| 977 | coff.globals.deinit(gpa); | 1034 | coff.globals.deinit(gpa); |
| 978 | coff.navs.deinit(gpa); | 1035 | coff.navs.deinit(gpa); |
| 979 | coff.uavs.deinit(gpa); | 1036 | coff.uavs.deinit(gpa); |
| ... | @@ -1035,8 +1092,13 @@ fn initHeaders( | ... | @@ -1035,8 +1092,13 @@ fn initHeaders( |
| 1035 | | 1092 | |
| 1036 | var expected_nodes_len: usize = Node.known_count; | 1093 | var expected_nodes_len: usize = Node.known_count; |
| 1037 | if (comp.zcu != null) { | 1094 | if (comp.zcu != null) { |
| | 1095 | // Section nodes |
| 1038 | expected_nodes_len += 3; | 1096 | expected_nodes_len += 3; |
| | 1097 | // Symbol table nodes |
| | 1098 | if (is_archive) expected_nodes_len += 6; |
| | 1099 | // Pseudo-sections and import / export table nodes |
| 1039 | if (is_image) expected_nodes_len += 9; | 1100 | if (is_image) expected_nodes_len += 9; |
| | 1101 | // TLS section nodes |
| 1040 | expected_nodes_len += @as(usize, @intFromBool(comp.config.any_non_single_threaded)) * 2; | 1102 | expected_nodes_len += @as(usize, @intFromBool(comp.config.any_non_single_threaded)) * 2; |
| 1041 | } | 1103 | } |
| 1042 | defer assert(coff.nodes.len == expected_nodes_len); | 1104 | defer assert(coff.nodes.len == expected_nodes_len); |
| ... | @@ -1294,10 +1356,26 @@ fn initHeaders( | ... | @@ -1294,10 +1356,26 @@ fn initHeaders( |
| 1294 | })); | 1356 | })); |
| 1295 | coff.nodes.appendAssumeCapacity(.section_table); | 1357 | coff.nodes.appendAssumeCapacity(.section_table); |
| 1296 | | 1358 | |
| | 1359 | const symbol_table_ni = Node.known.symbol_table; |
| | 1360 | assert(symbol_table_ni == try coff.mf.addLastChildNode(gpa, zcu_coff_parent_ni, .{ |
| | 1361 | .alignment = .@"4", |
| | 1362 | .fixed = true, |
| | 1363 | .moved = true, |
| | 1364 | })); |
| | 1365 | coff.nodes.appendAssumeCapacity(.symbol_table); |
| | 1366 | |
| | 1367 | const string_table_ni = Node.known.string_table; |
| | 1368 | assert(string_table_ni == try coff.mf.addLastChildNode(gpa, zcu_coff_parent_ni, .{ |
| | 1369 | .size = @sizeOf(u32), |
| | 1370 | .fixed = true, |
| | 1371 | .resized = true, |
| | 1372 | })); |
| | 1373 | coff.nodes.appendAssumeCapacity(.string_table); |
| | 1374 | |
| 1297 | assert(coff.nodes.len == Node.known_count); | 1375 | assert(coff.nodes.len == Node.known_count); |
| 1298 | | 1376 | |
| 1299 | try coff.symbol_table.ensureTotalCapacity(gpa, Symbol.Index.known_count); | 1377 | try coff.symbols.ensureTotalCapacity(gpa, Symbol.Index.known_count); |
| 1300 | coff.symbol_table.addOneAssumeCapacity().* = .{ | 1378 | coff.symbols.addOneAssumeCapacity().* = .{ |
| 1301 | .ni = .none, | 1379 | .ni = .none, |
| 1302 | .rva = 0, | 1380 | .rva = 0, |
| 1303 | .size = 0, | 1381 | .size = 0, |
| ... | @@ -1360,7 +1438,7 @@ fn initHeaders( | ... | @@ -1360,7 +1438,7 @@ fn initHeaders( |
| 1360 | }); | 1438 | }); |
| 1361 | coff.nodes.appendAssumeCapacity(.export_address_table); | 1439 | coff.nodes.appendAssumeCapacity(.export_address_table); |
| 1362 | | 1440 | |
| 1363 | try coff.symbol_table.ensureUnusedCapacity(gpa, 1); | 1441 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 1364 | coff.export_table.export_address_table_si = coff.addSymbolAssumeCapacity(); | 1442 | coff.export_table.export_address_table_si = coff.addSymbolAssumeCapacity(); |
| 1365 | | 1443 | |
| 1366 | const export_address_table_sym = coff.export_table.export_address_table_si.get(coff); | 1444 | const export_address_table_sym = coff.export_table.export_address_table_si.get(coff); |
| ... | @@ -1451,6 +1529,10 @@ fn computeNodeRva(coff: *Coff, ni: MappedFile.Node.Index) u32 { | ... | @@ -1451,6 +1529,10 @@ fn computeNodeRva(coff: *Coff, ni: MappedFile.Node.Index) u32 { |
| 1451 | .section_table, | 1529 | .section_table, |
| 1452 | .export_name_table, | 1530 | .export_name_table, |
| 1453 | .placeholder, | 1531 | .placeholder, |
| | 1532 | |
| | 1533 | .symbol_table, |
| | 1534 | .symbol_table_entry, |
| | 1535 | .string_table, |
| 1454 | => unreachable, | 1536 | => unreachable, |
| 1455 | .image_section => |si| si, | 1537 | .image_section => |si| si, |
| 1456 | .import_directory_table => break :parent_rva coff.targetLoad( | 1538 | .import_directory_table => break :parent_rva coff.targetLoad( |
| ... | @@ -1632,7 +1714,28 @@ pub fn dataDirectoryPtr( | ... | @@ -1632,7 +1714,28 @@ pub fn dataDirectoryPtr( |
| 1632 | } | 1714 | } |
| 1633 | | 1715 | |
| 1634 | pub fn sectionTableSlice(coff: *Coff) []std.coff.SectionHeader { | 1716 | pub fn sectionTableSlice(coff: *Coff) []std.coff.SectionHeader { |
| 1635 | return @ptrCast(@alignCast(Node.known.section_table.slice(&coff.mf))); | 1717 | return @ptrCast(@alignCast( |
| | 1718 | Node.known.section_table.slice(&coff.mf)[0 .. coff.section_table.items.len * @sizeOf(std.coff.SectionHeader)], |
| | 1719 | )); |
| | 1720 | } |
| | 1721 | |
| | 1722 | pub fn symbolTableEntryPtr(coff: *Coff, sti: SymbolTable.Index) *align(2) std.coff.Symbol { |
| | 1723 | return @ptrCast(@alignCast( |
| | 1724 | &Node.known.symbol_table.slice(&coff.mf)[@intFromEnum(sti) * std.coff.Symbol.sizeOf()], |
| | 1725 | )); |
| | 1726 | } |
| | 1727 | |
| | 1728 | pub fn symbolAuxSectionDefinitionPtr(coff: *Coff, si: Symbol.Index) *align(2) std.coff.SectionDefinition { |
| | 1729 | const sti = coff.symbol_table.entries.get(si).?.index; |
| | 1730 | |
| | 1731 | const symbol = coff.symbolTableEntryPtr(sti); |
| | 1732 | assert(symbol.storage_class == .STATIC and symbol.number_of_aux_symbols == 1); |
| | 1733 | |
| | 1734 | return @ptrCast(symbolTableEntryPtr(coff, @enumFromInt(@intFromEnum(sti) + 1))); |
| | 1735 | } |
| | 1736 | |
| | 1737 | pub fn symbolTableStringLenPtr(coff: *Coff) *align(2) u32 { |
| | 1738 | return @ptrCast(@alignCast(Node.known.string_table.slice(&coff.mf)[0..@sizeOf(u32)])); |
| 1636 | } | 1739 | } |
| 1637 | | 1740 | |
| 1638 | pub fn importDirectoryTableSlice(coff: *Coff) []std.coff.ImportDirectoryEntry { | 1741 | pub fn importDirectoryTableSlice(coff: *Coff) []std.coff.ImportDirectoryEntry { |
| ... | @@ -1662,7 +1765,7 @@ pub fn exportOrdinalTableSlice(coff: *Coff) []std.coff.ExportOrdinalTableEntry { | ... | @@ -1662,7 +1765,7 @@ pub fn exportOrdinalTableSlice(coff: *Coff) []std.coff.ExportOrdinalTableEntry { |
| 1662 | } | 1765 | } |
| 1663 | | 1766 | |
| 1664 | fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { | 1767 | fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { |
| 1665 | defer coff.symbol_table.addOneAssumeCapacity().* = .{ | 1768 | defer coff.symbols.addOneAssumeCapacity().* = .{ |
| 1666 | .ni = .none, | 1769 | .ni = .none, |
| 1667 | .rva = 0, | 1770 | .rva = 0, |
| 1668 | .size = 0, | 1771 | .size = 0, |
| ... | @@ -1670,7 +1773,7 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { | ... | @@ -1670,7 +1773,7 @@ fn addSymbolAssumeCapacity(coff: *Coff) Symbol.Index { |
| 1670 | .target_relocs = .none, | 1773 | .target_relocs = .none, |
| 1671 | .section_number = .UNDEFINED, | 1774 | .section_number = .UNDEFINED, |
| 1672 | }; | 1775 | }; |
| 1673 | return @enumFromInt(coff.symbol_table.items.len); | 1776 | return @enumFromInt(coff.symbols.items.len); |
| 1674 | } | 1777 | } |
| 1675 | | 1778 | |
| 1676 | fn initSymbolAssumeCapacity(coff: *Coff) !Symbol.Index { | 1779 | fn initSymbolAssumeCapacity(coff: *Coff) !Symbol.Index { |
| ... | @@ -1715,7 +1818,7 @@ fn getOrPutGlobalSymbol( | ... | @@ -1715,7 +1818,7 @@ fn getOrPutGlobalSymbol( |
| 1715 | lib_name: ?[]const u8, | 1818 | lib_name: ?[]const u8, |
| 1716 | ) !std.AutoArrayHashMapUnmanaged(GlobalName, Symbol.Index).GetOrPutResult { | 1819 | ) !std.AutoArrayHashMapUnmanaged(GlobalName, Symbol.Index).GetOrPutResult { |
| 1717 | const gpa = coff.base.comp.gpa; | 1820 | const gpa = coff.base.comp.gpa; |
| 1718 | try coff.symbol_table.ensureUnusedCapacity(gpa, 1); | 1821 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 1719 | const sym_gop = try coff.globals.getOrPut(gpa, .{ | 1822 | const sym_gop = try coff.globals.getOrPut(gpa, .{ |
| 1720 | .name = try coff.getOrPutString(name), | 1823 | .name = try coff.getOrPutString(name), |
| 1721 | .lib_name = try coff.getOrPutOptionalString(lib_name), | 1824 | .lib_name = try coff.getOrPutOptionalString(lib_name), |
| ... | @@ -1724,6 +1827,7 @@ fn getOrPutGlobalSymbol( | ... | @@ -1724,6 +1827,7 @@ fn getOrPutGlobalSymbol( |
| 1724 | sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity(); | 1827 | sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity(); |
| 1725 | coff.synth_prog_node.increaseEstimatedTotalItems(1); | 1828 | coff.synth_prog_node.increaseEstimatedTotalItems(1); |
| 1726 | } | 1829 | } |
| | 1830 | |
| 1727 | return sym_gop; | 1831 | return sym_gop; |
| 1728 | } | 1832 | } |
| 1729 | | 1833 | |
| ... | @@ -1758,7 +1862,7 @@ fn navSection( | ... | @@ -1758,7 +1862,7 @@ fn navSection( |
| 1758 | } | 1862 | } |
| 1759 | fn navMapIndex(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.NavMapIndex { | 1863 | fn navMapIndex(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.NavMapIndex { |
| 1760 | const gpa = zcu.gpa; | 1864 | const gpa = zcu.gpa; |
| 1761 | try coff.symbol_table.ensureUnusedCapacity(gpa, 1); | 1865 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 1762 | const sym_gop = try coff.navs.getOrPut(gpa, nav_index); | 1866 | const sym_gop = try coff.navs.getOrPut(gpa, nav_index); |
| 1763 | if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity(); | 1867 | if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity(); |
| 1764 | return @enumFromInt(sym_gop.index); | 1868 | return @enumFromInt(sym_gop.index); |
| ... | @@ -1776,7 +1880,7 @@ pub fn navSymbol(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbo | ... | @@ -1776,7 +1880,7 @@ pub fn navSymbol(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbo |
| 1776 | | 1880 | |
| 1777 | fn uavMapIndex(coff: *Coff, uav_val: InternPool.Index) !Node.UavMapIndex { | 1881 | fn uavMapIndex(coff: *Coff, uav_val: InternPool.Index) !Node.UavMapIndex { |
| 1778 | const gpa = coff.base.comp.gpa; | 1882 | const gpa = coff.base.comp.gpa; |
| 1779 | try coff.symbol_table.ensureUnusedCapacity(gpa, 1); | 1883 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 1780 | const sym_gop = try coff.uavs.getOrPut(gpa, uav_val); | 1884 | const sym_gop = try coff.uavs.getOrPut(gpa, uav_val); |
| 1781 | if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity(); | 1885 | if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity(); |
| 1782 | return @enumFromInt(sym_gop.index); | 1886 | return @enumFromInt(sym_gop.index); |
| ... | @@ -1788,7 +1892,7 @@ pub fn uavSymbol(coff: *Coff, uav_val: InternPool.Index) !Symbol.Index { | ... | @@ -1788,7 +1892,7 @@ pub fn uavSymbol(coff: *Coff, uav_val: InternPool.Index) !Symbol.Index { |
| 1788 | | 1892 | |
| 1789 | pub fn lazySymbol(coff: *Coff, lazy: link.File.LazySymbol) !Symbol.Index { | 1893 | pub fn lazySymbol(coff: *Coff, lazy: link.File.LazySymbol) !Symbol.Index { |
| 1790 | const gpa = coff.base.comp.gpa; | 1894 | const gpa = coff.base.comp.gpa; |
| 1791 | try coff.symbol_table.ensureUnusedCapacity(gpa, 1); | 1895 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 1792 | const sym_gop = try coff.lazy.getPtr(lazy.kind).map.getOrPut(gpa, lazy.ty); | 1896 | const sym_gop = try coff.lazy.getPtr(lazy.kind).map.getOrPut(gpa, lazy.ty); |
| 1793 | if (!sym_gop.found_existing) { | 1897 | if (!sym_gop.found_existing) { |
| 1794 | sym_gop.value_ptr.* = try coff.initSymbolAssumeCapacity(); | 1898 | sym_gop.value_ptr.* = try coff.initSymbolAssumeCapacity(); |
| ... | @@ -2004,13 +2108,185 @@ fn addMemberSymbol( | ... | @@ -2004,13 +2108,185 @@ fn addMemberSymbol( |
| 2004 | coff.pending_members.putAssumeCapacity(mi, {}); | 2108 | coff.pending_members.putAssumeCapacity(mi, {}); |
| 2005 | } | 2109 | } |
| 2006 | | 2110 | |
| | 2111 | fn addSymbolTableEntry( |
| | 2112 | coff: *Coff, |
| | 2113 | name: union(enum) { |
| | 2114 | bytes: []const u8, |
| | 2115 | string: String, |
| | 2116 | }, |
| | 2117 | si: Symbol.Index, |
| | 2118 | add: SymbolTable.Add, |
| | 2119 | ) !void { |
| | 2120 | assert(!coff.isImage()); |
| | 2121 | const gpa = coff.base.comp.gpa; |
| | 2122 | |
| | 2123 | const string, const name_slice = switch (name) { |
| | 2124 | .bytes => |bytes| .{ try coff.getOrPutString(bytes), bytes }, |
| | 2125 | .string => |s| .{ s, s.toSlice(coff) }, |
| | 2126 | }; |
| | 2127 | |
| | 2128 | const symbol_name: SymbolTable.SymbolName = if (name_slice.len > 8) index: { |
| | 2129 | const string_gop = try coff.symbol_table.string_offsets.getOrPut(gpa, string); |
| | 2130 | if (!string_gop.found_existing) { |
| | 2131 | const string_index = Node.known.string_table.location(&coff.mf).resolve(&coff.mf)[1]; |
| | 2132 | string_gop.value_ptr.* = @enumFromInt(string_index); |
| | 2133 | |
| | 2134 | try Node.known.string_table.resize(&coff.mf, gpa, string_index + name_slice.len + 1); |
| | 2135 | const slice = Node.known.string_table.slice(&coff.mf); |
| | 2136 | @memcpy(slice[string_index..][0..name_slice.len], name_slice); |
| | 2137 | slice[string_index + name_slice.len] = 0; |
| | 2138 | } |
| | 2139 | |
| | 2140 | break :index .{ .long = string_gop.value_ptr.* }; |
| | 2141 | } else .{ .short = name_slice }; |
| | 2142 | |
| | 2143 | const symbol_index = coff.targetLoad(&coff.headerPtr().number_of_symbols); |
| | 2144 | const symbols_added: u8 = switch (add) { |
| | 2145 | .section => count: { |
| | 2146 | const sym = si.get(coff); |
| | 2147 | |
| | 2148 | try coff.nodes.ensureUnusedCapacity(gpa, 2); |
| | 2149 | _ = try coff.addSymbolTableEntryAssumeCapacity( |
| | 2150 | symbol_name, |
| | 2151 | 0, |
| | 2152 | sym.section_number, |
| | 2153 | .{ |
| | 2154 | .complex_type = .NULL, |
| | 2155 | .base_type = .NULL, |
| | 2156 | }, |
| | 2157 | .STATIC, |
| | 2158 | 1, |
| | 2159 | ); |
| | 2160 | |
| | 2161 | // Aux entry ields are updated by flushMoved / flushResized |
| | 2162 | |
| | 2163 | try coff.symbol_table.entries.put(gpa, si, .{ |
| | 2164 | .entry_si = .null, |
| | 2165 | .index = @enumFromInt(symbol_index), |
| | 2166 | }); |
| | 2167 | |
| | 2168 | break :count 2; |
| | 2169 | }, |
| | 2170 | .global => |global| count: { |
| | 2171 | const sym = si.get(coff); |
| | 2172 | |
| | 2173 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| | 2174 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| | 2175 | |
| | 2176 | const entry_ni = try coff.addSymbolTableEntryAssumeCapacity( |
| | 2177 | symbol_name, |
| | 2178 | if (global.import) 0 else coff.computeNodeSectionOffset(sym.ni), |
| | 2179 | if (global.import) .UNDEFINED else sym.section_number, |
| | 2180 | .{ |
| | 2181 | .base_type = .NULL, |
| | 2182 | .complex_type = if (global.import or |
| | 2183 | Symbol.Index.text.get(coff).section_number == sym.section_number) |
| | 2184 | .FUNCTION |
| | 2185 | else |
| | 2186 | .NULL, |
| | 2187 | }, |
| | 2188 | .EXTERNAL, |
| | 2189 | 0, |
| | 2190 | ); |
| | 2191 | |
| | 2192 | const entry_si = coff.addSymbolAssumeCapacity(); |
| | 2193 | { |
| | 2194 | const entry_sym = entry_si.get(coff); |
| | 2195 | entry_sym.ni = entry_ni; |
| | 2196 | assert(entry_sym.loc_relocs == .none); |
| | 2197 | entry_sym.loc_relocs = @enumFromInt(coff.relocs.items.len); |
| | 2198 | entry_sym.section_number = .UNDEFINED; |
| | 2199 | } |
| | 2200 | |
| | 2201 | try coff.addReloc( |
| | 2202 | entry_si, |
| | 2203 | @offsetOf(std.coff.Symbol, "value"), |
| | 2204 | si, |
| | 2205 | 0, |
| | 2206 | .{ .AMD64 = .SECREL }, |
| | 2207 | ); |
| | 2208 | |
| | 2209 | try coff.symbol_table.entries.put(gpa, si, .{ |
| | 2210 | .entry_si = entry_si, |
| | 2211 | .index = @enumFromInt(symbol_index), |
| | 2212 | }); |
| | 2213 | |
| | 2214 | break :count 1; |
| | 2215 | }, |
| | 2216 | }; |
| | 2217 | |
| | 2218 | const new_num_symbols = symbol_index + symbols_added; |
| | 2219 | coff.targetStore(&coff.headerPtr().number_of_symbols, new_num_symbols); |
| | 2220 | coff.symbol_table.pending_shrink = |
| | 2221 | Node.known.symbol_table.location(&coff.mf).resolve(&coff.mf)[1] > |
| | 2222 | new_num_symbols * std.coff.Symbol.sizeOf(); |
| | 2223 | } |
| | 2224 | |
| | 2225 | /// Caller guarantees there is capacity for 1 + number_of_aux_symbols nodes. |
| | 2226 | /// Auxiliary nodes are zero-initialized. |
| | 2227 | fn addSymbolTableEntryAssumeCapacity( |
| | 2228 | coff: *Coff, |
| | 2229 | name: SymbolTable.SymbolName, |
| | 2230 | value: u32, |
| | 2231 | section_number: Symbol.SectionNumber, |
| | 2232 | @"type": std.coff.SymType, |
| | 2233 | storage_class: std.coff.StorageClass, |
| | 2234 | number_of_aux_symbols: u8, |
| | 2235 | ) !MappedFile.Node.Index { |
| | 2236 | const gpa = coff.base.comp.gpa; |
| | 2237 | |
| | 2238 | const entry_ni = try coff.mf.addLastChildNode(gpa, Node.known.symbol_table, .{ |
| | 2239 | .alignment = .@"2", |
| | 2240 | .size = std.coff.Symbol.sizeOf(), |
| | 2241 | .fixed = true, |
| | 2242 | }); |
| | 2243 | coff.nodes.appendAssumeCapacity(.symbol_table_entry); |
| | 2244 | |
| | 2245 | const entry: *align(2) std.coff.Symbol = @ptrCast(@alignCast(entry_ni.slice(&coff.mf))); |
| | 2246 | entry.* = .{ |
| | 2247 | .name = undefined, |
| | 2248 | .value = value, |
| | 2249 | .section_number = @enumFromInt(@intFromEnum(section_number)), |
| | 2250 | .type = @"type", |
| | 2251 | .storage_class = storage_class, |
| | 2252 | .number_of_aux_symbols = number_of_aux_symbols, |
| | 2253 | }; |
| | 2254 | |
| | 2255 | switch (name) { |
| | 2256 | .short => |s| { |
| | 2257 | @memcpy(entry.name[0..s.len], s); |
| | 2258 | @memset(entry.name[s.len..], 0); |
| | 2259 | }, |
| | 2260 | .long => |l| { |
| | 2261 | @memset(entry.name[0..4], 0); |
| | 2262 | const offset_ptr: *align(2) u32 = @ptrCast(entry.name[4..]); |
| | 2263 | coff.targetStore(offset_ptr, @intFromEnum(l)); |
| | 2264 | }, |
| | 2265 | } |
| | 2266 | |
| | 2267 | if (coff.targetEndian() != native_endian) |
| | 2268 | std.mem.byteSwapAllFields(std.coff.SectionHeader, entry.*); |
| | 2269 | |
| | 2270 | for (0..number_of_aux_symbols) |_| { |
| | 2271 | const aux_ni = try coff.mf.addLastChildNode(gpa, Node.known.symbol_table, .{ |
| | 2272 | .alignment = .@"2", |
| | 2273 | .size = std.coff.Symbol.sizeOf(), |
| | 2274 | .fixed = true, |
| | 2275 | }); |
| | 2276 | coff.nodes.appendAssumeCapacity(.symbol_table_entry); |
| | 2277 | @memset(aux_ni.slice(&coff.mf), 0); |
| | 2278 | } |
| | 2279 | |
| | 2280 | return entry_ni; |
| | 2281 | } |
| | 2282 | |
| 2007 | fn addSection(coff: *Coff, name: []const u8, flags: std.coff.SectionHeader.Flags) !Symbol.Index { | 2283 | fn addSection(coff: *Coff, name: []const u8, flags: std.coff.SectionHeader.Flags) !Symbol.Index { |
| 2008 | assert(coff.base.comp.zcu != null); | 2284 | assert(coff.base.comp.zcu != null); |
| 2009 | | 2285 | |
| 2010 | const gpa = coff.base.comp.gpa; | 2286 | const gpa = coff.base.comp.gpa; |
| 2011 | try coff.nodes.ensureUnusedCapacity(gpa, 1); | 2287 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 2012 | try coff.image_section_table.ensureUnusedCapacity(gpa, 1); | 2288 | try coff.section_table.ensureUnusedCapacity(gpa, 1); |
| 2013 | try coff.symbol_table.ensureUnusedCapacity(gpa, 1); | 2289 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 2014 | | 2290 | |
| 2015 | const coff_header = coff.headerPtr(); | 2291 | const coff_header = coff.headerPtr(); |
| 2016 | const section_index = coff.targetLoad(&coff_header.number_of_sections); | 2292 | const section_index = coff.targetLoad(&coff_header.number_of_sections); |
| ... | @@ -2022,19 +2298,19 @@ fn addSection(coff: *Coff, name: []const u8, flags: std.coff.SectionHeader.Flags | ... | @@ -2022,19 +2298,19 @@ fn addSection(coff: *Coff, name: []const u8, flags: std.coff.SectionHeader.Flags |
| 2022 | @sizeOf(std.coff.SectionHeader) * section_table_len, | 2298 | @sizeOf(std.coff.SectionHeader) * section_table_len, |
| 2023 | ); | 2299 | ); |
| 2024 | | 2300 | |
| 2025 | const parent_ni, const alignment = if (coff.isArchive()) | 2301 | const parent_ni = if (coff.isArchive()) |
| 2026 | .{ Node.known.zcu_member, .@"1" } | 2302 | Node.known.zcu_member |
| 2027 | else | 2303 | else |
| 2028 | .{ Node.known.file, coff.mf.flags.block_size }; | 2304 | Node.known.file; |
| 2029 | | 2305 | |
| 2030 | const ni = try coff.mf.addLastChildNode(gpa, parent_ni, .{ | 2306 | const ni = try coff.mf.addLastChildNode(gpa, parent_ni, .{ |
| 2031 | .alignment = alignment, | 2307 | .alignment = coff.mf.flags.block_size, |
| 2032 | .moved = true, | 2308 | .moved = true, |
| 2033 | .bubbles_moved = false, | 2309 | .bubbles_moved = false, |
| 2034 | }); | 2310 | }); |
| 2035 | | 2311 | |
| 2036 | const si = coff.addSymbolAssumeCapacity(); | 2312 | const si = coff.addSymbolAssumeCapacity(); |
| 2037 | coff.image_section_table.appendAssumeCapacity(si); | 2313 | coff.section_table.appendAssumeCapacity(si); |
| 2038 | coff.nodes.appendAssumeCapacity(.{ .image_section = si }); | 2314 | coff.nodes.appendAssumeCapacity(.{ .image_section = si }); |
| 2039 | const section_table = coff.sectionTableSlice(); | 2315 | const section_table = coff.sectionTableSlice(); |
| 2040 | | 2316 | |
| ... | @@ -2042,7 +2318,7 @@ fn addSection(coff: *Coff, name: []const u8, flags: std.coff.SectionHeader.Flags | ... | @@ -2042,7 +2318,7 @@ fn addSection(coff: *Coff, name: []const u8, flags: std.coff.SectionHeader.Flags |
| 2042 | const virtual_size = coff.optionalHeaderField(.section_alignment); | 2318 | const virtual_size = coff.optionalHeaderField(.section_alignment); |
| 2043 | const rva: u32 = switch (section_index) { | 2319 | const rva: u32 = switch (section_index) { |
| 2044 | 0 => @intCast(Node.known.header.location(&coff.mf).resolve(&coff.mf)[1]), | 2320 | 0 => @intCast(Node.known.header.location(&coff.mf).resolve(&coff.mf)[1]), |
| 2045 | else => coff.image_section_table.items[section_index - 1].get(coff).rva + | 2321 | else => coff.section_table.items[section_index - 1].get(coff).rva + |
| 2046 | coff.targetLoad(&section_table[section_index - 1].virtual_size), | 2322 | coff.targetLoad(&section_table[section_index - 1].virtual_size), |
| 2047 | }; | 2323 | }; |
| 2048 | | 2324 | |
| ... | @@ -2080,6 +2356,8 @@ fn addSection(coff: *Coff, name: []const u8, flags: std.coff.SectionHeader.Flags | ... | @@ -2080,6 +2356,8 @@ fn addSection(coff: *Coff, name: []const u8, flags: std.coff.SectionHeader.Flags |
| 2080 | @intCast(rva + virtual_size), | 2356 | @intCast(rva + virtual_size), |
| 2081 | ), | 2357 | ), |
| 2082 | } | 2358 | } |
| | 2359 | } else { |
| | 2360 | try coff.addSymbolTableEntry(.{ .bytes = name }, si, .section); |
| 2083 | } | 2361 | } |
| 2084 | | 2362 | |
| 2085 | return si; | 2363 | return si; |
| ... | @@ -2112,7 +2390,7 @@ fn pseudoSectionMapIndex( | ... | @@ -2112,7 +2390,7 @@ fn pseudoSectionMapIndex( |
| 2112 | else | 2390 | else |
| 2113 | .rdata; | 2391 | .rdata; |
| 2114 | try coff.nodes.ensureUnusedCapacity(gpa, 1); | 2392 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 2115 | try coff.symbol_table.ensureUnusedCapacity(gpa, 1); | 2393 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 2116 | const ni = try coff.mf.addLastChildNode(gpa, parent.node(coff), .{ .alignment = alignment }); | 2394 | const ni = try coff.mf.addLastChildNode(gpa, parent.node(coff), .{ .alignment = alignment }); |
| 2117 | const si = coff.addSymbolAssumeCapacity(); | 2395 | const si = coff.addSymbolAssumeCapacity(); |
| 2118 | pseudo_section_gop.value_ptr.* = si; | 2396 | pseudo_section_gop.value_ptr.* = si; |
| ... | @@ -2142,7 +2420,7 @@ fn objectSectionMapIndex( | ... | @@ -2142,7 +2420,7 @@ fn objectSectionMapIndex( |
| 2142 | name_slice[0 .. std.mem.indexOfScalar(u8, name_slice, '$') orelse name_slice.len], | 2420 | name_slice[0 .. std.mem.indexOfScalar(u8, name_slice, '$') orelse name_slice.len], |
| 2143 | ), alignment, attributes)).symbol(coff); | 2421 | ), alignment, attributes)).symbol(coff); |
| 2144 | try coff.nodes.ensureUnusedCapacity(gpa, 1); | 2422 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| 2145 | try coff.symbol_table.ensureUnusedCapacity(gpa, 1); | 2423 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 2146 | const parent_ni = parent.node(coff); | 2424 | const parent_ni = parent.node(coff); |
| 2147 | var prev_ni: MappedFile.Node.Index = .none; | 2425 | var prev_ni: MappedFile.Node.Index = .none; |
| 2148 | var next_it = parent_ni.children(&coff.mf); | 2426 | var next_it = parent_ni.children(&coff.mf); |
| ... | @@ -2251,6 +2529,8 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde | ... | @@ -2251,6 +2529,8 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 2251 | const sym = si.get(coff); | 2529 | const sym = si.get(coff); |
| 2252 | sym.ni = ni; | 2530 | sym.ni = ni; |
| 2253 | sym.section_number = sec_si.get(coff).section_number; | 2531 | sym.section_number = sec_si.get(coff).section_number; |
| | 2532 | |
| | 2533 | // TODO: Add symbol table entry |
| 2254 | }, | 2534 | }, |
| 2255 | else => si.deleteLocationRelocs(coff), | 2535 | else => si.deleteLocationRelocs(coff), |
| 2256 | } | 2536 | } |
| ... | @@ -2506,11 +2786,6 @@ pub fn flush( | ... | @@ -2506,11 +2786,6 @@ pub fn flush( |
| 2506 | _ = prog_node; | 2786 | _ = prog_node; |
| 2507 | while (try coff.idle(tid)) {} | 2787 | while (try coff.idle(tid)) {} |
| 2508 | | 2788 | |
| 2509 | // TODO: Second linker member symbol tables are built here | | |
| 2510 | if (isArchive(coff)) { | | |
| 2511 | //Member.Index.second.get(coff).content_ni; | | |
| 2512 | } | | |
| 2513 | | | |
| 2514 | const comp = coff.base.comp; | 2789 | const comp = coff.base.comp; |
| 2515 | | 2790 | |
| 2516 | // Implib generation should instead be done via building a MappedFile progressively | 2791 | // Implib generation should instead be done via building a MappedFile progressively |
| ... | @@ -2634,6 +2909,26 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { | ... | @@ -2634,6 +2909,26 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 2634 | coff.flushExportsSort(); | 2909 | coff.flushExportsSort(); |
| 2635 | break :task; | 2910 | break :task; |
| 2636 | } | 2911 | } |
| | 2912 | // TODO: This and the above task ideally run only once, as it's wasteful otherwise |
| | 2913 | if (coff.symbol_table.pending_shrink) { |
| | 2914 | coff.symbol_table.pending_shrink = false; |
| | 2915 | // TODO: Prog node |
| | 2916 | const number_of_symbols = coff.targetLoad(&coff.headerPtr().number_of_symbols); |
| | 2917 | Node.known.symbol_table.shrink( |
| | 2918 | &coff.mf, |
| | 2919 | comp.gpa, |
| | 2920 | number_of_symbols * std.coff.Symbol.sizeOf(), |
| | 2921 | true, |
| | 2922 | ) catch |err| switch (err) { |
| | 2923 | error.OutOfMemory => return error.OutOfMemory, |
| | 2924 | else => |e| return comp.link_diags.fail( |
| | 2925 | "linker failed to shrink symbol table: {t}", |
| | 2926 | .{e}, |
| | 2927 | ), |
| | 2928 | }; |
| | 2929 | |
| | 2930 | break :task; |
| | 2931 | } |
| 2637 | } | 2932 | } |
| 2638 | if (coff.pending_uavs.count() > 0) return true; | 2933 | if (coff.pending_uavs.count() > 0) return true; |
| 2639 | if (coff.globals.count() > coff.global_pending_index) return true; | 2934 | if (coff.globals.count() > coff.global_pending_index) return true; |
| ... | @@ -2641,6 +2936,7 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { | ... | @@ -2641,6 +2936,7 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 2641 | if (coff.mf.updates.items.len > 0) return true; | 2936 | if (coff.mf.updates.items.len > 0) return true; |
| 2642 | if (coff.pending_members.count() > 0) return true; | 2937 | if (coff.pending_members.count() > 0) return true; |
| 2643 | if (coff.export_table.pending_sort) return true; | 2938 | if (coff.export_table.pending_sort) return true; |
| | 2939 | if (coff.symbol_table.pending_shrink) return true; |
| 2644 | return false; | 2940 | return false; |
| 2645 | } | 2941 | } |
| 2646 | | 2942 | |
| ... | @@ -2733,14 +3029,28 @@ fn flushGlobal(coff: *Coff, pt: Zcu.PerThread, gmi: Node.GlobalMapIndex) !void { | ... | @@ -2733,14 +3029,28 @@ fn flushGlobal(coff: *Coff, pt: Zcu.PerThread, gmi: Node.GlobalMapIndex) !void { |
| 2733 | const gpa = zcu.gpa; | 3029 | const gpa = zcu.gpa; |
| 2734 | const gn = gmi.globalName(coff); | 3030 | const gn = gmi.globalName(coff); |
| 2735 | | 3031 | |
| 2736 | // TODO: We still need to emit a reloc for the __imp_Name symbol? | 3032 | if (!coff.isImage()) { |
| | 3033 | // TODO: What about data imports? |
| | 3034 | |
| | 3035 | // const si = gmi.symbol(coff); |
| | 3036 | // const sym = si.get(coff); |
| | 3037 | // sym.section_number = Symbol.Index.text.get(coff).section_number; |
| | 3038 | // assert(sym.loc_relocs == .none); |
| | 3039 | // sym.loc_relocs = @enumFromInt(coff.relocs.items.len); |
| | 3040 | // |
| | 3041 | // try coff.addSymbolTableEntry( |
| | 3042 | // .{ .bytes = gn.name.toSlice(coff) }, |
| | 3043 | // si, |
| | 3044 | // .{ .global = .{ .import = true } }, |
| | 3045 | // ); |
| 2737 | | 3046 | |
| 2738 | if (!coff.isImage()) return; | 3047 | return; |
| | 3048 | } |
| 2739 | | 3049 | |
| 2740 | if (gn.lib_name.toSlice(coff)) |lib_name| { | 3050 | if (gn.lib_name.toSlice(coff)) |lib_name| { |
| 2741 | const name = gn.name.toSlice(coff); | 3051 | const name = gn.name.toSlice(coff); |
| 2742 | try coff.nodes.ensureUnusedCapacity(gpa, 4); | 3052 | try coff.nodes.ensureUnusedCapacity(gpa, 4); |
| 2743 | try coff.symbol_table.ensureUnusedCapacity(gpa, 1); | 3053 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 2744 | | 3054 | |
| 2745 | const target_endian = coff.targetEndian(); | 3055 | const target_endian = coff.targetEndian(); |
| 2746 | const magic = coff.targetLoad(&coff.optionalHeaderStandardPtr().magic); | 3056 | const magic = coff.targetLoad(&coff.optionalHeaderStandardPtr().magic); |
| ... | @@ -2749,7 +3059,6 @@ fn flushGlobal(coff: *Coff, pt: Zcu.PerThread, gmi: Node.GlobalMapIndex) !void { | ... | @@ -2749,7 +3059,6 @@ fn flushGlobal(coff: *Coff, pt: Zcu.PerThread, gmi: Node.GlobalMapIndex) !void { |
| 2749 | .PE32 => .{ 4, .@"4" }, | 3059 | .PE32 => .{ 4, .@"4" }, |
| 2750 | .@"PE32+" => .{ 8, .@"8" }, | 3060 | .@"PE32+" => .{ 8, .@"8" }, |
| 2751 | }; | 3061 | }; |
| 2752 | | | |
| 2753 | const gop = try coff.import_table.entries.getOrPutAdapted( | 3062 | const gop = try coff.import_table.entries.getOrPutAdapted( |
| 2754 | gpa, | 3063 | gpa, |
| 2755 | lib_name, | 3064 | lib_name, |
| ... | @@ -2959,7 +3268,16 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { | ... | @@ -2959,7 +3268,16 @@ fn flushMoved(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 2959 | .data_directories, | 3268 | .data_directories, |
| 2960 | .section_table, | 3269 | .section_table, |
| 2961 | .placeholder, | 3270 | .placeholder, |
| | 3271 | |
| | 3272 | .symbol_table_entry, |
| | 3273 | .string_table, |
| 2962 | => if (!coff.isArchive()) unreachable, | 3274 | => if (!coff.isArchive()) unreachable, |
| | 3275 | .symbol_table => { |
| | 3276 | coff.targetStore( |
| | 3277 | &coff.headerPtr().pointer_to_symbol_table, |
| | 3278 | @intCast(ni.location(&coff.mf).resolve(&coff.mf)[0]), |
| | 3279 | ); |
| | 3280 | }, |
| 2963 | .archive_member_header => |mi| { | 3281 | .archive_member_header => |mi| { |
| 2964 | const member = mi.get(coff); | 3282 | const member = mi.get(coff); |
| 2965 | switch (member.kind) { | 3283 | switch (member.kind) { |
| ... | @@ -3121,7 +3439,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { | ... | @@ -3121,7 +3439,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 3121 | ), | 3439 | ), |
| 3122 | } | 3440 | } |
| 3123 | | 3441 | |
| 3124 | if (size > coff.image_section_table.items[0].get(coff).rva) try coff.virtualSlide( | 3442 | if (size > coff.section_table.items[0].get(coff).rva) try coff.virtualSlide( |
| 3125 | 0, | 3443 | 0, |
| 3126 | std.mem.alignForward( | 3444 | std.mem.alignForward( |
| 3127 | u32, | 3445 | u32, |
| ... | @@ -3159,6 +3477,12 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { | ... | @@ -3159,6 +3477,12 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 3159 | .data_directories, | 3477 | .data_directories, |
| 3160 | => unreachable, | 3478 | => unreachable, |
| 3161 | .section_table => {}, | 3479 | .section_table => {}, |
| | 3480 | .symbol_table => assert(!coff.isImage()), |
| | 3481 | .symbol_table_entry => unreachable, |
| | 3482 | .string_table => { |
| | 3483 | assert(!coff.isImage()); |
| | 3484 | coff.targetStore(coff.symbolTableStringLenPtr(), @intCast(size)); |
| | 3485 | }, |
| 3162 | .image_section => |si| { | 3486 | .image_section => |si| { |
| 3163 | const sym = si.get(coff); | 3487 | const sym = si.get(coff); |
| 3164 | const section_index = sym.section_number.toIndex(); | 3488 | const section_index = sym.section_number.toIndex(); |
| ... | @@ -3173,6 +3497,13 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { | ... | @@ -3173,6 +3497,13 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 3173 | coff.targetStore(&section.virtual_size, virtual_size); | 3497 | coff.targetStore(&section.virtual_size, virtual_size); |
| 3174 | try coff.virtualSlide(section_index + 1, sym.rva + virtual_size); | 3498 | try coff.virtualSlide(section_index + 1, sym.rva + virtual_size); |
| 3175 | } | 3499 | } |
| | 3500 | |
| | 3501 | if (coff.isArchive()) { |
| | 3502 | coff.targetStore( |
| | 3503 | &coff.symbolAuxSectionDefinitionPtr(si).length, |
| | 3504 | @intCast(size), |
| | 3505 | ); |
| | 3506 | } |
| 3176 | }, | 3507 | }, |
| 3177 | .import_directory_table => coff.targetStore( | 3508 | .import_directory_table => coff.targetStore( |
| 3178 | &coff.dataDirectoryPtr(.IMPORT).size, | 3509 | &coff.dataDirectoryPtr(.IMPORT).size, |
| ... | @@ -3298,7 +3629,7 @@ fn flushExportsSort(coff: *Coff) void { | ... | @@ -3298,7 +3629,7 @@ fn flushExportsSort(coff: *Coff) void { |
| 3298 | fn virtualSlide(coff: *Coff, start_section_index: usize, start_rva: u32) !void { | 3629 | fn virtualSlide(coff: *Coff, start_section_index: usize, start_rva: u32) !void { |
| 3299 | var rva = start_rva; | 3630 | var rva = start_rva; |
| 3300 | for ( | 3631 | for ( |
| 3301 | coff.image_section_table.items[start_section_index..], | 3632 | coff.section_table.items[start_section_index..], |
| 3302 | coff.sectionTableSlice()[start_section_index..], | 3633 | coff.sectionTableSlice()[start_section_index..], |
| 3303 | ) |section_si, *section| { | 3634 | ) |section_si, *section| { |
| 3304 | const section_sym = section_si.get(coff); | 3635 | const section_sym = section_si.get(coff); |
| ... | @@ -3343,7 +3674,7 @@ fn updateExportsInner( | ... | @@ -3343,7 +3674,7 @@ fn updateExportsInner( |
| 3343 | Value.fromInterned(uav).fmtValue(pt), | 3674 | Value.fromInterned(uav).fmtValue(pt), |
| 3344 | }), | 3675 | }), |
| 3345 | } | 3676 | } |
| 3346 | try coff.symbol_table.ensureUnusedCapacity(gpa, export_indices.len); | 3677 | try coff.symbols.ensureUnusedCapacity(gpa, export_indices.len); |
| 3347 | const exported_si: Symbol.Index = switch (exported) { | 3678 | const exported_si: Symbol.Index = switch (exported) { |
| 3348 | .nav => |nav| try coff.navSymbol(zcu, nav), | 3679 | .nav => |nav| try coff.navSymbol(zcu, nav), |
| 3349 | .uav => |uav| @enumFromInt(@intFromEnum(try coff.lowerUav( | 3680 | .uav => |uav| @enumFromInt(@intFromEnum(try coff.lowerUav( |
| ... | @@ -3376,13 +3707,20 @@ fn updateExportsInner( | ... | @@ -3376,13 +3707,20 @@ fn updateExportsInner( |
| 3376 | std.mem.byteSwapAllFields(std.coff.ImageDataDirectory, tls_directory); | 3707 | std.mem.byteSwapAllFields(std.coff.ImageDataDirectory, tls_directory); |
| 3377 | } | 3708 | } |
| 3378 | | 3709 | |
| 3379 | if (coff.isArchive()) | 3710 | if (coff.isArchive()) { |
| 3380 | try coff.addMemberSymbol( | 3711 | try coff.addMemberSymbol( |
| 3381 | symbol_gop.key_ptr.*.name, | 3712 | symbol_gop.key_ptr.*.name, |
| 3382 | coff.getNode(Node.known.zcu_member).archive_member, | 3713 | coff.getNode(Node.known.zcu_member).archive_member, |
| 3383 | export_si, | 3714 | export_si, |
| 3384 | ); | 3715 | ); |
| 3385 | | 3716 | |
| | 3717 | try coff.addSymbolTableEntry( |
| | 3718 | .{ .bytes = name }, |
| | 3719 | export_si, |
| | 3720 | .{ .global = .{ .import = false } }, |
| | 3721 | ); |
| | 3722 | } |
| | 3723 | |
| 3386 | if (coff.export_table.ni == .none) continue; | 3724 | if (coff.export_table.ni == .none) continue; |
| 3387 | | 3725 | |
| 3388 | const entries_ctx = ExportTable.Adapter{ .coff = coff }; | 3726 | const entries_ctx = ExportTable.Adapter{ .coff = coff }; |
| ... | @@ -3425,8 +3763,7 @@ fn updateExportsInner( | ... | @@ -3425,8 +3763,7 @@ fn updateExportsInner( |
| 3425 | coff.targetStore(&edt.number_of_names, @intCast(export_count)); | 3763 | coff.targetStore(&edt.number_of_names, @intCast(export_count)); |
| 3426 | edt.number_of_entries = edt.number_of_names; | 3764 | edt.number_of_entries = edt.number_of_names; |
| 3427 | | 3765 | |
| 3428 | // TODO: If we had an estimate of the total number of exports this could be a lot more efficient | 3766 | // TODO: These should all be resized ahead of time to fit all exports (after https://github.com/ziglang/zig/issues/23616) |
| 3429 | | | |
| 3430 | try coff.export_table.export_address_table_si.node(coff).resize( | 3767 | try coff.export_table.export_address_table_si.node(coff).resize( |
| 3431 | &coff.mf, | 3768 | &coff.mf, |
| 3432 | gpa, | 3769 | gpa, |