| ... | @@ -1423,23 +1423,22 @@ fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void { | ... | @@ -1423,23 +1423,22 @@ fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void { |
| 1423 | const sym = self.getSymbol(current); | 1423 | const sym = self.getSymbol(current); |
| 1424 | const sym_name = self.getSymbolName(current); | 1424 | const sym_name = self.getSymbolName(current); |
| 1425 | | 1425 | |
| 1426 | const global_index = self.resolver.get(sym_name) orelse { | 1426 | const gop = try self.getOrPutGlobalPtr(sym_name); |
| 1427 | const name = try gpa.dupe(u8, sym_name); | 1427 | if (!gop.found_existing) { |
| 1428 | const global_index = try self.allocateGlobal(); | 1428 | gop.value_ptr.* = current; |
| 1429 | self.globals.items[global_index] = current; | | |
| 1430 | try self.resolver.putNoClobber(gpa, name, global_index); | | |
| 1431 | if (sym.section_number == .UNDEFINED) { | 1429 | if (sym.section_number == .UNDEFINED) { |
| 1432 | try self.unresolved.putNoClobber(gpa, global_index, false); | 1430 | try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, false); |
| 1433 | } | 1431 | } |
| 1434 | return; | 1432 | return; |
| 1435 | }; | 1433 | } |
| 1436 | | 1434 | |
| 1437 | log.debug("TODO finish resolveGlobalSymbols implementation", .{}); | 1435 | log.debug("TODO finish resolveGlobalSymbols implementation", .{}); |
| 1438 | | 1436 | |
| 1439 | if (sym.section_number == .UNDEFINED) return; | 1437 | if (sym.section_number == .UNDEFINED) return; |
| 1440 | | 1438 | |
| 1441 | _ = self.unresolved.swapRemove(global_index); | 1439 | _ = self.unresolved.swapRemove(self.getGlobalIndex(sym_name).?); |
| 1442 | self.globals.items[global_index] = current; | 1440 | |
| | 1441 | gop.value_ptr.* = current; |
| 1443 | } | 1442 | } |
| 1444 | | 1443 | |
| 1445 | pub fn flush(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void { | 1444 | pub fn flush(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| ... | @@ -1544,23 +1543,23 @@ pub fn getDeclVAddr( | ... | @@ -1544,23 +1543,23 @@ pub fn getDeclVAddr( |
| 1544 | } | 1543 | } |
| 1545 | | 1544 | |
| 1546 | pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 { | 1545 | pub fn getGlobalSymbol(self: *Coff, name: []const u8) !u32 { |
| 1547 | if (self.resolver.get(name)) |global_index| { | 1546 | const gop = try self.getOrPutGlobalPtr(name); |
| 1548 | return self.globals.items[global_index].sym_index; | 1547 | |
| | 1548 | if (gop.found_existing) { |
| | 1549 | return gop.value_ptr.sym_index; |
| 1549 | } | 1550 | } |
| 1550 | | 1551 | |
| 1551 | const gpa = self.base.allocator; | | |
| 1552 | const sym_index = try self.allocateSymbol(); | 1552 | const sym_index = try self.allocateSymbol(); |
| 1553 | const global_index = try self.allocateGlobal(); | | |
| 1554 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 1553 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 1555 | self.globals.items[global_index] = sym_loc; | 1554 | gop.value_ptr.* = sym_loc; |
| 1556 | | 1555 | |
| | 1556 | const gpa = self.base.allocator; |
| 1557 | const sym_name = try gpa.dupe(u8, name); | 1557 | const sym_name = try gpa.dupe(u8, name); |
| 1558 | const sym = self.getSymbolPtr(sym_loc); | 1558 | const sym = self.getSymbolPtr(sym_loc); |
| 1559 | try self.setSymbolName(sym, sym_name); | 1559 | try self.setSymbolName(sym, sym_name); |
| 1560 | sym.storage_class = .EXTERNAL; | 1560 | sym.storage_class = .EXTERNAL; |
| 1561 | | 1561 | |
| 1562 | try self.resolver.putNoClobber(gpa, sym_name, global_index); | 1562 | try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(name).?, true); |
| 1563 | try self.unresolved.putNoClobber(gpa, global_index, true); | | |
| 1564 | | 1563 | |
| 1565 | return sym_index; | 1564 | return sym_index; |
| 1566 | } | 1565 | } |
| ... | @@ -2061,6 +2060,43 @@ pub fn getSymbolName(self: *const Coff, sym_loc: SymbolWithLoc) []const u8 { | ... | @@ -2061,6 +2060,43 @@ pub fn getSymbolName(self: *const Coff, sym_loc: SymbolWithLoc) []const u8 { |
| 2061 | return self.strtab.get(offset).?; | 2060 | return self.strtab.get(offset).?; |
| 2062 | } | 2061 | } |
| 2063 | | 2062 | |
| | 2063 | /// Returns pointer to the global entry for `name` if one exists. |
| | 2064 | pub fn getGlobalPtr(self: *Coff, name: []const u8) ?*SymbolWithLoc { |
| | 2065 | const global_index = self.resolver.get(name) orelse return null; |
| | 2066 | return &self.globals.items[global_index]; |
| | 2067 | } |
| | 2068 | |
| | 2069 | /// Returns the global entry for `name` if one exists. |
| | 2070 | pub fn getGlobal(self: *const Coff, name: []const u8) ?SymbolWithLoc { |
| | 2071 | const global_index = self.resolver.get(name) orelse return null; |
| | 2072 | return self.globals.items[global_index]; |
| | 2073 | } |
| | 2074 | |
| | 2075 | /// Returns the index of the global entry for `name` if one exists. |
| | 2076 | pub fn getGlobalIndex(self: *const Coff, name: []const u8) ?u32 { |
| | 2077 | return self.resolver.get(name); |
| | 2078 | } |
| | 2079 | |
| | 2080 | const GetOrPutGlobalPtrResult = struct { |
| | 2081 | found_existing: bool, |
| | 2082 | value_ptr: *SymbolWithLoc, |
| | 2083 | }; |
| | 2084 | |
| | 2085 | /// Return pointer to the global entry for `name` if one exists. |
| | 2086 | /// Puts a new global entry for `name` if one doesn't exist, and |
| | 2087 | /// returns a pointer to it. |
| | 2088 | pub fn getOrPutGlobalPtr(self: *Coff, name: []const u8) !GetOrPutGlobalPtrResult { |
| | 2089 | if (self.getGlobalPtr(name)) |ptr| { |
| | 2090 | return GetOrPutGlobalPtrResult{ .found_existing = true, .value_ptr = ptr }; |
| | 2091 | } |
| | 2092 | const gpa = self.base.allocator; |
| | 2093 | const global_index = try self.allocateGlobal(); |
| | 2094 | const global_name = try gpa.dupe(u8, name); |
| | 2095 | _ = try self.resolver.put(gpa, global_name, global_index); |
| | 2096 | const ptr = &self.globals.items[global_index]; |
| | 2097 | return GetOrPutGlobalPtrResult{ .found_existing = false, .value_ptr = ptr }; |
| | 2098 | } |
| | 2099 | |
| 2064 | /// Returns atom if there is an atom referenced by the symbol described by `sym_loc` descriptor. | 2100 | /// Returns atom if there is an atom referenced by the symbol described by `sym_loc` descriptor. |
| 2065 | /// Returns null on failure. | 2101 | /// Returns null on failure. |
| 2066 | pub fn getAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { | 2102 | pub fn getAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { |