| ... | @@ -79,13 +79,13 @@ entry_addr: ?u32 = null, | ... | @@ -79,13 +79,13 @@ entry_addr: ?u32 = null, |
| 79 | /// We store them here so that we can properly dispose of any allocated | 79 | /// We store them here so that we can properly dispose of any allocated |
| 80 | /// memory within the atom in the incremental linker. | 80 | /// memory within the atom in the incremental linker. |
| 81 | /// TODO consolidate this. | 81 | /// TODO consolidate this. |
| 82 | decls: std.AutoHashMapUnmanaged(Module.Decl.Index, ?u16) = .{}, | 82 | decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 83 | | 83 | |
| 84 | /// List of atoms that are either synthetic or map directly to the Zig source program. | 84 | /// List of atoms that are either synthetic or map directly to the Zig source program. |
| 85 | managed_atoms: std.ArrayListUnmanaged(*Atom) = .{}, | 85 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| 86 | | 86 | |
| 87 | /// Table of atoms indexed by the symbol index. | 87 | /// Table of atoms indexed by the symbol index. |
| 88 | atom_by_index_table: std.AutoHashMapUnmanaged(u32, *Atom) = .{}, | 88 | atom_by_index_table: std.AutoHashMapUnmanaged(u32, Atom.Index) = .{}, |
| 89 | | 89 | |
| 90 | /// Table of unnamed constants associated with a parent `Decl`. | 90 | /// Table of unnamed constants associated with a parent `Decl`. |
| 91 | /// We store them here so that we can free the constants whenever the `Decl` | 91 | /// We store them here so that we can free the constants whenever the `Decl` |
| ... | @@ -124,9 +124,9 @@ const Entry = struct { | ... | @@ -124,9 +124,9 @@ const Entry = struct { |
| 124 | sym_index: u32, | 124 | sym_index: u32, |
| 125 | }; | 125 | }; |
| 126 | | 126 | |
| 127 | const RelocTable = std.AutoHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(Relocation)); | 127 | const RelocTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); |
| 128 | const BaseRelocationTable = std.AutoHashMapUnmanaged(*Atom, std.ArrayListUnmanaged(u32)); | 128 | const BaseRelocationTable = std.AutoHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| 129 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(*Atom)); | 129 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| 130 | | 130 | |
| 131 | const default_file_alignment: u16 = 0x200; | 131 | const default_file_alignment: u16 = 0x200; |
| 132 | const default_size_of_stack_reserve: u32 = 0x1000000; | 132 | const default_size_of_stack_reserve: u32 = 0x1000000; |
| ... | @@ -137,7 +137,7 @@ const default_size_of_heap_commit: u32 = 0x1000; | ... | @@ -137,7 +137,7 @@ const default_size_of_heap_commit: u32 = 0x1000; |
| 137 | const Section = struct { | 137 | const Section = struct { |
| 138 | header: coff.SectionHeader, | 138 | header: coff.SectionHeader, |
| 139 | | 139 | |
| 140 | last_atom: ?*Atom = null, | 140 | last_atom_index: ?Atom.Index = null, |
| 141 | | 141 | |
| 142 | /// A list of atoms that have surplus capacity. This list can have false | 142 | /// A list of atoms that have surplus capacity. This list can have false |
| 143 | /// positives, as functions grow and shrink over time, only sometimes being added | 143 | /// positives, as functions grow and shrink over time, only sometimes being added |
| ... | @@ -154,7 +154,34 @@ const Section = struct { | ... | @@ -154,7 +154,34 @@ const Section = struct { |
| 154 | /// overcapacity can be negative. A simple way to have negative overcapacity is to | 154 | /// overcapacity can be negative. A simple way to have negative overcapacity is to |
| 155 | /// allocate a fresh atom, which will have ideal capacity, and then grow it | 155 | /// allocate a fresh atom, which will have ideal capacity, and then grow it |
| 156 | /// by 1 byte. It will then have -1 overcapacity. | 156 | /// by 1 byte. It will then have -1 overcapacity. |
| 157 | free_list: std.ArrayListUnmanaged(*Atom) = .{}, | 157 | free_list: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| | 158 | }; |
| | 159 | |
| | 160 | const DeclMetadata = struct { |
| | 161 | atom: Atom.Index, |
| | 162 | section: u16, |
| | 163 | /// A list of all exports aliases of this Decl. |
| | 164 | exports: std.ArrayListUnmanaged(u32) = .{}, |
| | 165 | |
| | 166 | fn getExport(m: DeclMetadata, coff_file: *const Coff, name: []const u8) ?u32 { |
| | 167 | for (m.exports.items) |exp| { |
| | 168 | if (mem.eql(u8, name, coff_file.getSymbolName(.{ |
| | 169 | .sym_index = exp, |
| | 170 | .file = null, |
| | 171 | }))) return exp; |
| | 172 | } |
| | 173 | return null; |
| | 174 | } |
| | 175 | |
| | 176 | fn getExportPtr(m: *DeclMetadata, coff_file: *Coff, name: []const u8) ?*u32 { |
| | 177 | for (m.exports.items) |*exp| { |
| | 178 | if (mem.eql(u8, name, coff_file.getSymbolName(.{ |
| | 179 | .sym_index = exp.*, |
| | 180 | .file = null, |
| | 181 | }))) return exp; |
| | 182 | } |
| | 183 | return null; |
| | 184 | } |
| 158 | }; | 185 | }; |
| 159 | | 186 | |
| 160 | pub const PtrWidth = enum { | 187 | pub const PtrWidth = enum { |
| ... | @@ -170,10 +197,6 @@ pub const PtrWidth = enum { | ... | @@ -170,10 +197,6 @@ pub const PtrWidth = enum { |
| 170 | }; | 197 | }; |
| 171 | pub const SrcFn = void; | 198 | pub const SrcFn = void; |
| 172 | | 199 | |
| 173 | pub const Export = struct { | | |
| 174 | sym_index: ?u32 = null, | | |
| 175 | }; | | |
| 176 | | | |
| 177 | pub const SymbolWithLoc = struct { | 200 | pub const SymbolWithLoc = struct { |
| 178 | // Index into the respective symbol table. | 201 | // Index into the respective symbol table. |
| 179 | sym_index: u32, | 202 | sym_index: u32, |
| ... | @@ -271,11 +294,7 @@ pub fn deinit(self: *Coff) void { | ... | @@ -271,11 +294,7 @@ pub fn deinit(self: *Coff) void { |
| 271 | } | 294 | } |
| 272 | self.sections.deinit(gpa); | 295 | self.sections.deinit(gpa); |
| 273 | | 296 | |
| 274 | for (self.managed_atoms.items) |atom| { | 297 | self.atoms.deinit(gpa); |
| 275 | gpa.destroy(atom); | | |
| 276 | } | | |
| 277 | self.managed_atoms.deinit(gpa); | | |
| 278 | | | |
| 279 | self.locals.deinit(gpa); | 298 | self.locals.deinit(gpa); |
| 280 | self.globals.deinit(gpa); | 299 | self.globals.deinit(gpa); |
| 281 | | 300 | |
| ... | @@ -297,7 +316,15 @@ pub fn deinit(self: *Coff) void { | ... | @@ -297,7 +316,15 @@ pub fn deinit(self: *Coff) void { |
| 297 | self.imports.deinit(gpa); | 316 | self.imports.deinit(gpa); |
| 298 | self.imports_free_list.deinit(gpa); | 317 | self.imports_free_list.deinit(gpa); |
| 299 | self.imports_table.deinit(gpa); | 318 | self.imports_table.deinit(gpa); |
| 300 | self.decls.deinit(gpa); | 319 | |
| | 320 | { |
| | 321 | var it = self.decls.iterator(); |
| | 322 | while (it.next()) |entry| { |
| | 323 | entry.value_ptr.exports.deinit(gpa); |
| | 324 | } |
| | 325 | self.decls.deinit(gpa); |
| | 326 | } |
| | 327 | |
| 301 | self.atom_by_index_table.deinit(gpa); | 328 | self.atom_by_index_table.deinit(gpa); |
| 302 | | 329 | |
| 303 | { | 330 | { |
| ... | @@ -461,17 +488,18 @@ fn growSectionVM(self: *Coff, sect_id: u32, needed_size: u32) !void { | ... | @@ -461,17 +488,18 @@ fn growSectionVM(self: *Coff, sect_id: u32, needed_size: u32) !void { |
| 461 | // TODO: enforce order by increasing VM addresses in self.sections container. | 488 | // TODO: enforce order by increasing VM addresses in self.sections container. |
| 462 | // This is required by the loader anyhow as far as I can tell. | 489 | // This is required by the loader anyhow as far as I can tell. |
| 463 | for (self.sections.items(.header)[sect_id + 1 ..]) |*next_header, next_sect_id| { | 490 | for (self.sections.items(.header)[sect_id + 1 ..]) |*next_header, next_sect_id| { |
| 464 | const maybe_last_atom = &self.sections.items(.last_atom)[sect_id + 1 + next_sect_id]; | 491 | const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id + 1 + next_sect_id]; |
| 465 | next_header.virtual_address += diff; | 492 | next_header.virtual_address += diff; |
| 466 | | 493 | |
| 467 | if (maybe_last_atom.*) |last_atom| { | 494 | if (maybe_last_atom_index) |last_atom_index| { |
| 468 | var atom = last_atom; | 495 | var atom_index = last_atom_index; |
| 469 | while (true) { | 496 | while (true) { |
| | 497 | const atom = self.getAtom(atom_index); |
| 470 | const sym = atom.getSymbolPtr(self); | 498 | const sym = atom.getSymbolPtr(self); |
| 471 | sym.value += diff; | 499 | sym.value += diff; |
| 472 | | 500 | |
| 473 | if (atom.prev) |prev| { | 501 | if (atom.prev_index) |prev_index| { |
| 474 | atom = prev; | 502 | atom_index = prev_index; |
| 475 | } else break; | 503 | } else break; |
| 476 | } | 504 | } |
| 477 | } | 505 | } |
| ... | @@ -480,14 +508,15 @@ fn growSectionVM(self: *Coff, sect_id: u32, needed_size: u32) !void { | ... | @@ -480,14 +508,15 @@ fn growSectionVM(self: *Coff, sect_id: u32, needed_size: u32) !void { |
| 480 | header.virtual_size = increased_size; | 508 | header.virtual_size = increased_size; |
| 481 | } | 509 | } |
| 482 | | 510 | |
| 483 | fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u32 { | 511 | fn allocateAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignment: u32) !u32 { |
| 484 | const tracy = trace(@src()); | 512 | const tracy = trace(@src()); |
| 485 | defer tracy.end(); | 513 | defer tracy.end(); |
| 486 | | 514 | |
| | 515 | const atom = self.getAtom(atom_index); |
| 487 | const sect_id = @enumToInt(atom.getSymbol(self).section_number) - 1; | 516 | const sect_id = @enumToInt(atom.getSymbol(self).section_number) - 1; |
| 488 | const header = &self.sections.items(.header)[sect_id]; | 517 | const header = &self.sections.items(.header)[sect_id]; |
| 489 | const free_list = &self.sections.items(.free_list)[sect_id]; | 518 | const free_list = &self.sections.items(.free_list)[sect_id]; |
| 490 | const maybe_last_atom = &self.sections.items(.last_atom)[sect_id]; | 519 | const maybe_last_atom_index = &self.sections.items(.last_atom_index)[sect_id]; |
| 491 | const new_atom_ideal_capacity = if (header.isCode()) padToIdeal(new_atom_size) else new_atom_size; | 520 | const new_atom_ideal_capacity = if (header.isCode()) padToIdeal(new_atom_size) else new_atom_size; |
| 492 | | 521 | |
| 493 | // We use these to indicate our intention to update metadata, placing the new atom, | 522 | // We use these to indicate our intention to update metadata, placing the new atom, |
| ... | @@ -495,7 +524,7 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u | ... | @@ -495,7 +524,7 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u |
| 495 | // It would be simpler to do it inside the for loop below, but that would cause a | 524 | // It would be simpler to do it inside the for loop below, but that would cause a |
| 496 | // problem if an error was returned later in the function. So this action | 525 | // problem if an error was returned later in the function. So this action |
| 497 | // is actually carried out at the end of the function, when errors are no longer possible. | 526 | // is actually carried out at the end of the function, when errors are no longer possible. |
| 498 | var atom_placement: ?*Atom = null; | 527 | var atom_placement: ?Atom.Index = null; |
| 499 | var free_list_removal: ?usize = null; | 528 | var free_list_removal: ?usize = null; |
| 500 | | 529 | |
| 501 | // First we look for an appropriately sized free list node. | 530 | // First we look for an appropriately sized free list node. |
| ... | @@ -503,7 +532,8 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u | ... | @@ -503,7 +532,8 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u |
| 503 | var vaddr = blk: { | 532 | var vaddr = blk: { |
| 504 | var i: usize = 0; | 533 | var i: usize = 0; |
| 505 | while (i < free_list.items.len) { | 534 | while (i < free_list.items.len) { |
| 506 | const big_atom = free_list.items[i]; | 535 | const big_atom_index = free_list.items[i]; |
| | 536 | const big_atom = self.getAtom(big_atom_index); |
| 507 | // We now have a pointer to a live atom that has too much capacity. | 537 | // We now have a pointer to a live atom that has too much capacity. |
| 508 | // Is it enough that we could fit this new atom? | 538 | // Is it enough that we could fit this new atom? |
| 509 | const sym = big_atom.getSymbol(self); | 539 | const sym = big_atom.getSymbol(self); |
| ... | @@ -531,34 +561,43 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u | ... | @@ -531,34 +561,43 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u |
| 531 | const keep_free_list_node = remaining_capacity >= min_text_capacity; | 561 | const keep_free_list_node = remaining_capacity >= min_text_capacity; |
| 532 | | 562 | |
| 533 | // Set up the metadata to be updated, after errors are no longer possible. | 563 | // Set up the metadata to be updated, after errors are no longer possible. |
| 534 | atom_placement = big_atom; | 564 | atom_placement = big_atom_index; |
| 535 | if (!keep_free_list_node) { | 565 | if (!keep_free_list_node) { |
| 536 | free_list_removal = i; | 566 | free_list_removal = i; |
| 537 | } | 567 | } |
| 538 | break :blk new_start_vaddr; | 568 | break :blk new_start_vaddr; |
| 539 | } else if (maybe_last_atom.*) |last| { | 569 | } else if (maybe_last_atom_index.*) |last_index| { |
| | 570 | const last = self.getAtom(last_index); |
| 540 | const last_symbol = last.getSymbol(self); | 571 | const last_symbol = last.getSymbol(self); |
| 541 | const ideal_capacity = if (header.isCode()) padToIdeal(last.size) else last.size; | 572 | const ideal_capacity = if (header.isCode()) padToIdeal(last.size) else last.size; |
| 542 | const ideal_capacity_end_vaddr = last_symbol.value + ideal_capacity; | 573 | const ideal_capacity_end_vaddr = last_symbol.value + ideal_capacity; |
| 543 | const new_start_vaddr = mem.alignForwardGeneric(u32, ideal_capacity_end_vaddr, alignment); | 574 | const new_start_vaddr = mem.alignForwardGeneric(u32, ideal_capacity_end_vaddr, alignment); |
| 544 | atom_placement = last; | 575 | atom_placement = last_index; |
| 545 | break :blk new_start_vaddr; | 576 | break :blk new_start_vaddr; |
| 546 | } else { | 577 | } else { |
| 547 | break :blk mem.alignForwardGeneric(u32, header.virtual_address, alignment); | 578 | break :blk mem.alignForwardGeneric(u32, header.virtual_address, alignment); |
| 548 | } | 579 | } |
| 549 | }; | 580 | }; |
| 550 | | 581 | |
| 551 | const expand_section = atom_placement == null or atom_placement.?.next == null; | 582 | const expand_section = if (atom_placement) |placement_index| |
| | 583 | self.getAtom(placement_index).next_index == null |
| | 584 | else |
| | 585 | true; |
| 552 | if (expand_section) { | 586 | if (expand_section) { |
| 553 | const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); | 587 | const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); |
| 554 | const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address; | 588 | const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address; |
| 555 | if (needed_size > sect_capacity) { | 589 | if (needed_size > sect_capacity) { |
| 556 | const new_offset = self.findFreeSpace(needed_size, default_file_alignment); | 590 | const new_offset = self.findFreeSpace(needed_size, default_file_alignment); |
| 557 | const current_size = if (maybe_last_atom.*) |last_atom| blk: { | 591 | const current_size = if (maybe_last_atom_index.*) |last_atom_index| blk: { |
| | 592 | const last_atom = self.getAtom(last_atom_index); |
| 558 | const sym = last_atom.getSymbol(self); | 593 | const sym = last_atom.getSymbol(self); |
| 559 | break :blk (sym.value + last_atom.size) - header.virtual_address; | 594 | break :blk (sym.value + last_atom.size) - header.virtual_address; |
| 560 | } else 0; | 595 | } else 0; |
| 561 | log.debug("moving {s} from 0x{x} to 0x{x}", .{ self.getSectionName(header), header.pointer_to_raw_data, new_offset }); | 596 | log.debug("moving {s} from 0x{x} to 0x{x}", .{ |
| | 597 | self.getSectionName(header), |
| | 598 | header.pointer_to_raw_data, |
| | 599 | new_offset, |
| | 600 | }); |
| 562 | const amt = try self.base.file.?.copyRangeAll( | 601 | const amt = try self.base.file.?.copyRangeAll( |
| 563 | header.pointer_to_raw_data, | 602 | header.pointer_to_raw_data, |
| 564 | self.base.file.?, | 603 | self.base.file.?, |
| ... | @@ -577,26 +616,34 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u | ... | @@ -577,26 +616,34 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u |
| 577 | | 616 | |
| 578 | header.virtual_size = @max(header.virtual_size, needed_size); | 617 | header.virtual_size = @max(header.virtual_size, needed_size); |
| 579 | header.size_of_raw_data = needed_size; | 618 | header.size_of_raw_data = needed_size; |
| 580 | maybe_last_atom.* = atom; | 619 | maybe_last_atom_index.* = atom_index; |
| 581 | } | 620 | } |
| 582 | | 621 | |
| 583 | atom.size = new_atom_size; | 622 | { |
| 584 | atom.alignment = alignment; | 623 | const atom_ptr = self.getAtomPtr(atom_index); |
| | 624 | atom_ptr.size = new_atom_size; |
| | 625 | atom_ptr.alignment = alignment; |
| | 626 | } |
| 585 | | 627 | |
| 586 | if (atom.prev) |prev| { | 628 | if (atom.prev_index) |prev_index| { |
| 587 | prev.next = atom.next; | 629 | const prev = self.getAtomPtr(prev_index); |
| | 630 | prev.next_index = atom.next_index; |
| 588 | } | 631 | } |
| 589 | if (atom.next) |next| { | 632 | if (atom.next_index) |next_index| { |
| 590 | next.prev = atom.prev; | 633 | const next = self.getAtomPtr(next_index); |
| | 634 | next.prev_index = atom.prev_index; |
| 591 | } | 635 | } |
| 592 | | 636 | |
| 593 | if (atom_placement) |big_atom| { | 637 | if (atom_placement) |big_atom_index| { |
| 594 | atom.prev = big_atom; | 638 | const big_atom = self.getAtomPtr(big_atom_index); |
| 595 | atom.next = big_atom.next; | 639 | const atom_ptr = self.getAtomPtr(atom_index); |
| 596 | big_atom.next = atom; | 640 | atom_ptr.prev_index = big_atom_index; |
| | 641 | atom_ptr.next_index = big_atom.next_index; |
| | 642 | big_atom.next_index = atom_index; |
| 597 | } else { | 643 | } else { |
| 598 | atom.prev = null; | 644 | const atom_ptr = self.getAtomPtr(atom_index); |
| 599 | atom.next = null; | 645 | atom_ptr.prev_index = null; |
| | 646 | atom_ptr.next_index = null; |
| 600 | } | 647 | } |
| 601 | if (free_list_removal) |i| { | 648 | if (free_list_removal) |i| { |
| 602 | _ = free_list.swapRemove(i); | 649 | _ = free_list.swapRemove(i); |
| ... | @@ -701,24 +748,37 @@ pub fn allocateImportEntry(self: *Coff, target: SymbolWithLoc) !u32 { | ... | @@ -701,24 +748,37 @@ pub fn allocateImportEntry(self: *Coff, target: SymbolWithLoc) !u32 { |
| 701 | return index; | 748 | return index; |
| 702 | } | 749 | } |
| 703 | | 750 | |
| 704 | fn createGotAtom(self: *Coff, target: SymbolWithLoc) !*Atom { | 751 | pub fn createAtom(self: *Coff) !Atom.Index { |
| 705 | const gpa = self.base.allocator; | 752 | const gpa = self.base.allocator; |
| 706 | const atom = try gpa.create(Atom); | 753 | const atom_index = @intCast(Atom.Index, self.atoms.items.len); |
| 707 | errdefer gpa.destroy(atom); | 754 | const atom = try self.atoms.addOne(gpa); |
| 708 | atom.* = Atom.empty; | 755 | const sym_index = try self.allocateSymbol(); |
| 709 | try atom.ensureInitialized(self); | 756 | try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index); |
| | 757 | atom.* = .{ |
| | 758 | .sym_index = sym_index, |
| | 759 | .file = null, |
| | 760 | .size = 0, |
| | 761 | .alignment = 0, |
| | 762 | .prev_index = null, |
| | 763 | .next_index = null, |
| | 764 | }; |
| | 765 | log.debug("creating ATOM(%{d}) at index {d}", .{ sym_index, atom_index }); |
| | 766 | return atom_index; |
| | 767 | } |
| | 768 | |
| | 769 | fn createGotAtom(self: *Coff, target: SymbolWithLoc) !Atom.Index { |
| | 770 | const atom_index = try self.createAtom(); |
| | 771 | const atom = self.getAtomPtr(atom_index); |
| 710 | atom.size = @sizeOf(u64); | 772 | atom.size = @sizeOf(u64); |
| 711 | atom.alignment = @alignOf(u64); | 773 | atom.alignment = @alignOf(u64); |
| 712 | | 774 | |
| 713 | try self.managed_atoms.append(gpa, atom); | | |
| 714 | | | |
| 715 | const sym = atom.getSymbolPtr(self); | 775 | const sym = atom.getSymbolPtr(self); |
| 716 | sym.section_number = @intToEnum(coff.SectionNumber, self.got_section_index.? + 1); | 776 | sym.section_number = @intToEnum(coff.SectionNumber, self.got_section_index.? + 1); |
| 717 | sym.value = try self.allocateAtom(atom, atom.size, atom.alignment); | 777 | sym.value = try self.allocateAtom(atom_index, atom.size, atom.alignment); |
| 718 | | 778 | |
| 719 | log.debug("allocated GOT atom at 0x{x}", .{sym.value}); | 779 | log.debug("allocated GOT atom at 0x{x}", .{sym.value}); |
| 720 | | 780 | |
| 721 | try atom.addRelocation(self, .{ | 781 | try Atom.addRelocation(self, atom_index, .{ |
| 722 | .type = .direct, | 782 | .type = .direct, |
| 723 | .target = target, | 783 | .target = target, |
| 724 | .offset = 0, | 784 | .offset = 0, |
| ... | @@ -732,49 +792,46 @@ fn createGotAtom(self: *Coff, target: SymbolWithLoc) !*Atom { | ... | @@ -732,49 +792,46 @@ fn createGotAtom(self: *Coff, target: SymbolWithLoc) !*Atom { |
| 732 | .UNDEFINED => @panic("TODO generate a binding for undefined GOT target"), | 792 | .UNDEFINED => @panic("TODO generate a binding for undefined GOT target"), |
| 733 | .ABSOLUTE => {}, | 793 | .ABSOLUTE => {}, |
| 734 | .DEBUG => unreachable, // not possible | 794 | .DEBUG => unreachable, // not possible |
| 735 | else => try atom.addBaseRelocation(self, 0), | 795 | else => try Atom.addBaseRelocation(self, atom_index, 0), |
| 736 | } | 796 | } |
| 737 | | 797 | |
| 738 | return atom; | 798 | return atom_index; |
| 739 | } | 799 | } |
| 740 | | 800 | |
| 741 | fn createImportAtom(self: *Coff) !*Atom { | 801 | fn createImportAtom(self: *Coff) !Atom.Index { |
| 742 | const gpa = self.base.allocator; | 802 | const atom_index = try self.createAtom(); |
| 743 | const atom = try gpa.create(Atom); | 803 | const atom = self.getAtomPtr(atom_index); |
| 744 | errdefer gpa.destroy(atom); | | |
| 745 | atom.* = Atom.empty; | | |
| 746 | try atom.ensureInitialized(self); | | |
| 747 | atom.size = @sizeOf(u64); | 804 | atom.size = @sizeOf(u64); |
| 748 | atom.alignment = @alignOf(u64); | 805 | atom.alignment = @alignOf(u64); |
| 749 | | 806 | |
| 750 | try self.managed_atoms.append(gpa, atom); | | |
| 751 | | | |
| 752 | const sym = atom.getSymbolPtr(self); | 807 | const sym = atom.getSymbolPtr(self); |
| 753 | sym.section_number = @intToEnum(coff.SectionNumber, self.idata_section_index.? + 1); | 808 | sym.section_number = @intToEnum(coff.SectionNumber, self.idata_section_index.? + 1); |
| 754 | sym.value = try self.allocateAtom(atom, atom.size, atom.alignment); | 809 | sym.value = try self.allocateAtom(atom_index, atom.size, atom.alignment); |
| 755 | | 810 | |
| 756 | log.debug("allocated import atom at 0x{x}", .{sym.value}); | 811 | log.debug("allocated import atom at 0x{x}", .{sym.value}); |
| 757 | | 812 | |
| 758 | return atom; | 813 | return atom_index; |
| 759 | } | 814 | } |
| 760 | | 815 | |
| 761 | fn growAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u32 { | 816 | fn growAtom(self: *Coff, atom_index: Atom.Index, new_atom_size: u32, alignment: u32) !u32 { |
| | 817 | const atom = self.getAtom(atom_index); |
| 762 | const sym = atom.getSymbol(self); | 818 | const sym = atom.getSymbol(self); |
| 763 | const align_ok = mem.alignBackwardGeneric(u32, sym.value, alignment) == sym.value; | 819 | const align_ok = mem.alignBackwardGeneric(u32, sym.value, alignment) == sym.value; |
| 764 | const need_realloc = !align_ok or new_atom_size > atom.capacity(self); | 820 | const need_realloc = !align_ok or new_atom_size > atom.capacity(self); |
| 765 | if (!need_realloc) return sym.value; | 821 | if (!need_realloc) return sym.value; |
| 766 | return self.allocateAtom(atom, new_atom_size, alignment); | 822 | return self.allocateAtom(atom_index, new_atom_size, alignment); |
| 767 | } | 823 | } |
| 768 | | 824 | |
| 769 | fn shrinkAtom(self: *Coff, atom: *Atom, new_block_size: u32) void { | 825 | fn shrinkAtom(self: *Coff, atom_index: Atom.Index, new_block_size: u32) void { |
| 770 | _ = self; | 826 | _ = self; |
| 771 | _ = atom; | 827 | _ = atom_index; |
| 772 | _ = new_block_size; | 828 | _ = new_block_size; |
| 773 | // TODO check the new capacity, and if it crosses the size threshold into a big enough | 829 | // TODO check the new capacity, and if it crosses the size threshold into a big enough |
| 774 | // capacity, insert a free list node for it. | 830 | // capacity, insert a free list node for it. |
| 775 | } | 831 | } |
| 776 | | 832 | |
| 777 | fn writeAtom(self: *Coff, atom: *Atom, code: []const u8) !void { | 833 | fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []const u8) !void { |
| | 834 | const atom = self.getAtom(atom_index); |
| 778 | const sym = atom.getSymbol(self); | 835 | const sym = atom.getSymbol(self); |
| 779 | const section = self.sections.get(@enumToInt(sym.section_number) - 1); | 836 | const section = self.sections.get(@enumToInt(sym.section_number) - 1); |
| 780 | const file_offset = section.header.pointer_to_raw_data + sym.value - section.header.virtual_address; | 837 | const file_offset = section.header.pointer_to_raw_data + sym.value - section.header.virtual_address; |
| ... | @@ -784,18 +841,18 @@ fn writeAtom(self: *Coff, atom: *Atom, code: []const u8) !void { | ... | @@ -784,18 +841,18 @@ fn writeAtom(self: *Coff, atom: *Atom, code: []const u8) !void { |
| 784 | file_offset + code.len, | 841 | file_offset + code.len, |
| 785 | }); | 842 | }); |
| 786 | try self.base.file.?.pwriteAll(code, file_offset); | 843 | try self.base.file.?.pwriteAll(code, file_offset); |
| 787 | try self.resolveRelocs(atom); | 844 | try self.resolveRelocs(atom_index); |
| 788 | } | 845 | } |
| 789 | | 846 | |
| 790 | fn writePtrWidthAtom(self: *Coff, atom: *Atom) !void { | 847 | fn writePtrWidthAtom(self: *Coff, atom_index: Atom.Index) !void { |
| 791 | switch (self.ptr_width) { | 848 | switch (self.ptr_width) { |
| 792 | .p32 => { | 849 | .p32 => { |
| 793 | var buffer: [@sizeOf(u32)]u8 = [_]u8{0} ** @sizeOf(u32); | 850 | var buffer: [@sizeOf(u32)]u8 = [_]u8{0} ** @sizeOf(u32); |
| 794 | try self.writeAtom(atom, &buffer); | 851 | try self.writeAtom(atom_index, &buffer); |
| 795 | }, | 852 | }, |
| 796 | .p64 => { | 853 | .p64 => { |
| 797 | var buffer: [@sizeOf(u64)]u8 = [_]u8{0} ** @sizeOf(u64); | 854 | var buffer: [@sizeOf(u64)]u8 = [_]u8{0} ** @sizeOf(u64); |
| 798 | try self.writeAtom(atom, &buffer); | 855 | try self.writeAtom(atom_index, &buffer); |
| 799 | }, | 856 | }, |
| 800 | } | 857 | } |
| 801 | } | 858 | } |
| ... | @@ -815,7 +872,8 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { | ... | @@ -815,7 +872,8 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { |
| 815 | var it = self.relocs.valueIterator(); | 872 | var it = self.relocs.valueIterator(); |
| 816 | while (it.next()) |relocs| { | 873 | while (it.next()) |relocs| { |
| 817 | for (relocs.items) |*reloc| { | 874 | for (relocs.items) |*reloc| { |
| 818 | const target_atom = reloc.getTargetAtom(self) orelse continue; | 875 | const target_atom_index = reloc.getTargetAtomIndex(self) orelse continue; |
| | 876 | const target_atom = self.getAtom(target_atom_index); |
| 819 | const target_sym = target_atom.getSymbol(self); | 877 | const target_sym = target_atom.getSymbol(self); |
| 820 | if (target_sym.value < addr) continue; | 878 | if (target_sym.value < addr) continue; |
| 821 | reloc.dirty = true; | 879 | reloc.dirty = true; |
| ... | @@ -823,24 +881,26 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { | ... | @@ -823,24 +881,26 @@ fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { |
| 823 | } | 881 | } |
| 824 | } | 882 | } |
| 825 | | 883 | |
| 826 | fn resolveRelocs(self: *Coff, atom: *Atom) !void { | 884 | fn resolveRelocs(self: *Coff, atom_index: Atom.Index) !void { |
| 827 | const relocs = self.relocs.get(atom) orelse return; | 885 | const relocs = self.relocs.get(atom_index) orelse return; |
| 828 | | 886 | |
| 829 | log.debug("relocating '{s}'", .{atom.getName(self)}); | 887 | log.debug("relocating '{s}'", .{self.getAtom(atom_index).getName(self)}); |
| 830 | | 888 | |
| 831 | for (relocs.items) |*reloc| { | 889 | for (relocs.items) |*reloc| { |
| 832 | if (!reloc.dirty) continue; | 890 | if (!reloc.dirty) continue; |
| 833 | try reloc.resolve(atom, self); | 891 | try reloc.resolve(atom_index, self); |
| 834 | } | 892 | } |
| 835 | } | 893 | } |
| 836 | | 894 | |
| 837 | fn freeAtom(self: *Coff, atom: *Atom) void { | 895 | fn freeAtom(self: *Coff, atom_index: Atom.Index) void { |
| 838 | log.debug("freeAtom {*}", .{atom}); | 896 | log.debug("freeAtom {d}", .{atom_index}); |
| | 897 | |
| | 898 | const gpa = self.base.allocator; |
| 839 | | 899 | |
| 840 | // Remove any relocs and base relocs associated with this Atom | 900 | // Remove any relocs and base relocs associated with this Atom |
| 841 | self.freeRelocationsForAtom(atom); | 901 | Atom.freeRelocations(self, atom_index); |
| 842 | | 902 | |
| 843 | const gpa = self.base.allocator; | 903 | const atom = self.getAtom(atom_index); |
| 844 | const sym = atom.getSymbol(self); | 904 | const sym = atom.getSymbol(self); |
| 845 | const sect_id = @enumToInt(sym.section_number) - 1; | 905 | const sect_id = @enumToInt(sym.section_number) - 1; |
| 846 | const free_list = &self.sections.items(.free_list)[sect_id]; | 906 | const free_list = &self.sections.items(.free_list)[sect_id]; |
| ... | @@ -849,45 +909,46 @@ fn freeAtom(self: *Coff, atom: *Atom) void { | ... | @@ -849,45 +909,46 @@ fn freeAtom(self: *Coff, atom: *Atom) void { |
| 849 | var i: usize = 0; | 909 | var i: usize = 0; |
| 850 | // TODO turn free_list into a hash map | 910 | // TODO turn free_list into a hash map |
| 851 | while (i < free_list.items.len) { | 911 | while (i < free_list.items.len) { |
| 852 | if (free_list.items[i] == atom) { | 912 | if (free_list.items[i] == atom_index) { |
| 853 | _ = free_list.swapRemove(i); | 913 | _ = free_list.swapRemove(i); |
| 854 | continue; | 914 | continue; |
| 855 | } | 915 | } |
| 856 | if (free_list.items[i] == atom.prev) { | 916 | if (free_list.items[i] == atom.prev_index) { |
| 857 | already_have_free_list_node = true; | 917 | already_have_free_list_node = true; |
| 858 | } | 918 | } |
| 859 | i += 1; | 919 | i += 1; |
| 860 | } | 920 | } |
| 861 | } | 921 | } |
| 862 | | 922 | |
| 863 | const maybe_last_atom = &self.sections.items(.last_atom)[sect_id]; | 923 | const maybe_last_atom_index = &self.sections.items(.last_atom_index)[sect_id]; |
| 864 | if (maybe_last_atom.*) |last_atom| { | 924 | if (maybe_last_atom_index.*) |last_atom_index| { |
| 865 | if (last_atom == atom) { | 925 | if (last_atom_index == atom_index) { |
| 866 | if (atom.prev) |prev| { | 926 | if (atom.prev_index) |prev_index| { |
| 867 | // TODO shrink the section size here | 927 | // TODO shrink the section size here |
| 868 | maybe_last_atom.* = prev; | 928 | maybe_last_atom_index.* = prev_index; |
| 869 | } else { | 929 | } else { |
| 870 | maybe_last_atom.* = null; | 930 | maybe_last_atom_index.* = null; |
| 871 | } | 931 | } |
| 872 | } | 932 | } |
| 873 | } | 933 | } |
| 874 | | 934 | |
| 875 | if (atom.prev) |prev| { | 935 | if (atom.prev_index) |prev_index| { |
| 876 | prev.next = atom.next; | 936 | const prev = self.getAtomPtr(prev_index); |
| | 937 | prev.next_index = atom.next_index; |
| 877 | | 938 | |
| 878 | if (!already_have_free_list_node and prev.freeListEligible(self)) { | 939 | if (!already_have_free_list_node and prev.*.freeListEligible(self)) { |
| 879 | // The free list is heuristics, it doesn't have to be perfect, so we can | 940 | // The free list is heuristics, it doesn't have to be perfect, so we can |
| 880 | // ignore the OOM here. | 941 | // ignore the OOM here. |
| 881 | free_list.append(gpa, prev) catch {}; | 942 | free_list.append(gpa, prev_index) catch {}; |
| 882 | } | 943 | } |
| 883 | } else { | 944 | } else { |
| 884 | atom.prev = null; | 945 | self.getAtomPtr(atom_index).prev_index = null; |
| 885 | } | 946 | } |
| 886 | | 947 | |
| 887 | if (atom.next) |next| { | 948 | if (atom.next_index) |next_index| { |
| 888 | next.prev = atom.prev; | 949 | self.getAtomPtr(next_index).prev_index = atom.prev_index; |
| 889 | } else { | 950 | } else { |
| 890 | atom.next = null; | 951 | self.getAtomPtr(atom_index).next_index = null; |
| 891 | } | 952 | } |
| 892 | | 953 | |
| 893 | // Appending to free lists is allowed to fail because the free lists are heuristics based anyway. | 954 | // Appending to free lists is allowed to fail because the free lists are heuristics based anyway. |
| ... | @@ -910,7 +971,7 @@ fn freeAtom(self: *Coff, atom: *Atom) void { | ... | @@ -910,7 +971,7 @@ fn freeAtom(self: *Coff, atom: *Atom) void { |
| 910 | self.locals.items[sym_index].section_number = .UNDEFINED; | 971 | self.locals.items[sym_index].section_number = .UNDEFINED; |
| 911 | _ = self.atom_by_index_table.remove(sym_index); | 972 | _ = self.atom_by_index_table.remove(sym_index); |
| 912 | log.debug(" adding local symbol index {d} to free list", .{sym_index}); | 973 | log.debug(" adding local symbol index {d} to free list", .{sym_index}); |
| 913 | atom.sym_index = 0; | 974 | self.getAtomPtr(atom_index).sym_index = 0; |
| 914 | } | 975 | } |
| 915 | | 976 | |
| 916 | pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { | 977 | pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { |
| ... | @@ -927,15 +988,10 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live | ... | @@ -927,15 +988,10 @@ pub fn updateFunc(self: *Coff, module: *Module, func: *Module.Fn, air: Air, live |
| 927 | | 988 | |
| 928 | const decl_index = func.owner_decl; | 989 | const decl_index = func.owner_decl; |
| 929 | const decl = module.declPtr(decl_index); | 990 | const decl = module.declPtr(decl_index); |
| 930 | const atom = &decl.link.coff; | 991 | |
| 931 | try atom.ensureInitialized(self); | 992 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 932 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); | 993 | self.freeUnnamedConsts(decl_index); |
| 933 | if (gop.found_existing) { | 994 | Atom.freeRelocations(self, atom_index); |
| 934 | self.freeUnnamedConsts(decl_index); | | |
| 935 | self.freeRelocationsForAtom(&decl.link.coff); | | |
| 936 | } else { | | |
| 937 | gop.value_ptr.* = null; | | |
| 938 | } | | |
| 939 | | 995 | |
| 940 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); | 996 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 941 | defer code_buffer.deinit(); | 997 | defer code_buffer.deinit(); |
| ... | @@ -979,11 +1035,8 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In | ... | @@ -979,11 +1035,8 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In |
| 979 | } | 1035 | } |
| 980 | const unnamed_consts = gop.value_ptr; | 1036 | const unnamed_consts = gop.value_ptr; |
| 981 | | 1037 | |
| 982 | const atom = try gpa.create(Atom); | 1038 | const atom_index = try self.createAtom(); |
| 983 | errdefer gpa.destroy(atom); | 1039 | const atom = self.getAtomPtr(atom_index); |
| 984 | atom.* = Atom.empty; | | |
| 985 | try atom.ensureInitialized(self); | | |
| 986 | try self.managed_atoms.append(gpa, atom); | | |
| 987 | | 1040 | |
| 988 | const sym_name = blk: { | 1041 | const sym_name = blk: { |
| 989 | const decl_name = try decl.getFullyQualifiedName(mod); | 1042 | const decl_name = try decl.getFullyQualifiedName(mod); |
| ... | @@ -1012,15 +1065,15 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In | ... | @@ -1012,15 +1065,15 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In |
| 1012 | const required_alignment = tv.ty.abiAlignment(self.base.options.target); | 1065 | const required_alignment = tv.ty.abiAlignment(self.base.options.target); |
| 1013 | atom.alignment = required_alignment; | 1066 | atom.alignment = required_alignment; |
| 1014 | atom.size = @intCast(u32, code.len); | 1067 | atom.size = @intCast(u32, code.len); |
| 1015 | atom.getSymbolPtr(self).value = try self.allocateAtom(atom, atom.size, atom.alignment); | 1068 | atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, atom.alignment); |
| 1016 | errdefer self.freeAtom(atom); | 1069 | errdefer self.freeAtom(atom_index); |
| 1017 | | 1070 | |
| 1018 | try unnamed_consts.append(gpa, atom); | 1071 | try unnamed_consts.append(gpa, atom_index); |
| 1019 | | 1072 | |
| 1020 | log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, atom.getSymbol(self).value }); | 1073 | log.debug("allocated atom for {s} at 0x{x}", .{ sym_name, atom.getSymbol(self).value }); |
| 1021 | log.debug(" (required alignment 0x{x})", .{required_alignment}); | 1074 | log.debug(" (required alignment 0x{x})", .{required_alignment}); |
| 1022 | | 1075 | |
| 1023 | try self.writeAtom(atom, code); | 1076 | try self.writeAtom(atom_index, code); |
| 1024 | | 1077 | |
| 1025 | return atom.getSymbolIndex().?; | 1078 | return atom.getSymbolIndex().?; |
| 1026 | } | 1079 | } |
| ... | @@ -1047,14 +1100,9 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! | ... | @@ -1047,14 +1100,9 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! |
| 1047 | } | 1100 | } |
| 1048 | } | 1101 | } |
| 1049 | | 1102 | |
| 1050 | const atom = &decl.link.coff; | 1103 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 1051 | try atom.ensureInitialized(self); | 1104 | Atom.freeRelocations(self, atom_index); |
| 1052 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); | 1105 | const atom = self.getAtom(atom_index); |
| 1053 | if (gop.found_existing) { | | |
| 1054 | self.freeRelocationsForAtom(atom); | | |
| 1055 | } else { | | |
| 1056 | gop.value_ptr.* = null; | | |
| 1057 | } | | |
| 1058 | | 1106 | |
| 1059 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); | 1107 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 1060 | defer code_buffer.deinit(); | 1108 | defer code_buffer.deinit(); |
| ... | @@ -1064,7 +1112,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! | ... | @@ -1064,7 +1112,7 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! |
| 1064 | .ty = decl.ty, | 1112 | .ty = decl.ty, |
| 1065 | .val = decl_val, | 1113 | .val = decl_val, |
| 1066 | }, &code_buffer, .none, .{ | 1114 | }, &code_buffer, .none, .{ |
| 1067 | .parent_atom_index = decl.link.coff.getSymbolIndex().?, | 1115 | .parent_atom_index = atom.getSymbolIndex().?, |
| 1068 | }); | 1116 | }); |
| 1069 | const code = switch (res) { | 1117 | const code = switch (res) { |
| 1070 | .ok => code_buffer.items, | 1118 | .ok => code_buffer.items, |
| ... | @@ -1082,7 +1130,20 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! | ... | @@ -1082,7 +1130,20 @@ pub fn updateDecl(self: *Coff, module: *Module, decl_index: Module.Decl.Index) ! |
| 1082 | return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); | 1130 | return self.updateDeclExports(module, decl_index, module.getDeclExports(decl_index)); |
| 1083 | } | 1131 | } |
| 1084 | | 1132 | |
| 1085 | fn getDeclOutputSection(self: *Coff, decl: *Module.Decl) u16 { | 1133 | pub fn getOrCreateAtomForDecl(self: *Coff, decl_index: Module.Decl.Index) !Atom.Index { |
| | 1134 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); |
| | 1135 | if (!gop.found_existing) { |
| | 1136 | gop.value_ptr.* = .{ |
| | 1137 | .atom = try self.createAtom(), |
| | 1138 | .section = self.getDeclOutputSection(decl_index), |
| | 1139 | .exports = .{}, |
| | 1140 | }; |
| | 1141 | } |
| | 1142 | return gop.value_ptr.atom; |
| | 1143 | } |
| | 1144 | |
| | 1145 | fn getDeclOutputSection(self: *Coff, decl_index: Module.Decl.Index) u16 { |
| | 1146 | const decl = self.base.options.module.?.declPtr(decl_index); |
| 1086 | const ty = decl.ty; | 1147 | const ty = decl.ty; |
| 1087 | const zig_ty = ty.zigTypeTag(); | 1148 | const zig_ty = ty.zigTypeTag(); |
| 1088 | const val = decl.val; | 1149 | const val = decl.val; |
| ... | @@ -1117,14 +1178,11 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, | ... | @@ -1117,14 +1178,11 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, |
| 1117 | log.debug("updateDeclCode {s}{*}", .{ decl_name, decl }); | 1178 | log.debug("updateDeclCode {s}{*}", .{ decl_name, decl }); |
| 1118 | const required_alignment = decl.getAlignment(self.base.options.target); | 1179 | const required_alignment = decl.getAlignment(self.base.options.target); |
| 1119 | | 1180 | |
| 1120 | const decl_ptr = self.decls.getPtr(decl_index).?; | 1181 | const decl_metadata = self.decls.get(decl_index).?; |
| 1121 | if (decl_ptr.* == null) { | 1182 | const atom_index = decl_metadata.atom; |
| 1122 | decl_ptr.* = self.getDeclOutputSection(decl); | 1183 | const atom = self.getAtom(atom_index); |
| 1123 | } | 1184 | const sect_index = decl_metadata.section; |
| 1124 | const sect_index = decl_ptr.*.?; | | |
| 1125 | | | |
| 1126 | const code_len = @intCast(u32, code.len); | 1185 | const code_len = @intCast(u32, code.len); |
| 1127 | const atom = &decl.link.coff; | | |
| 1128 | | 1186 | |
| 1129 | if (atom.size != 0) { | 1187 | if (atom.size != 0) { |
| 1130 | const sym = atom.getSymbolPtr(self); | 1188 | const sym = atom.getSymbolPtr(self); |
| ... | @@ -1135,7 +1193,7 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, | ... | @@ -1135,7 +1193,7 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, |
| 1135 | const capacity = atom.capacity(self); | 1193 | const capacity = atom.capacity(self); |
| 1136 | const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment); | 1194 | const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment); |
| 1137 | if (need_realloc) { | 1195 | if (need_realloc) { |
| 1138 | const vaddr = try self.growAtom(atom, code_len, required_alignment); | 1196 | const vaddr = try self.growAtom(atom_index, code_len, required_alignment); |
| 1139 | log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, sym.value, vaddr }); | 1197 | log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl_name, sym.value, vaddr }); |
| 1140 | log.debug(" (required alignment 0x{x}", .{required_alignment}); | 1198 | log.debug(" (required alignment 0x{x}", .{required_alignment}); |
| 1141 | | 1199 | |
| ... | @@ -1143,49 +1201,43 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, | ... | @@ -1143,49 +1201,43 @@ fn updateDeclCode(self: *Coff, decl_index: Module.Decl.Index, code: []const u8, |
| 1143 | sym.value = vaddr; | 1201 | sym.value = vaddr; |
| 1144 | log.debug(" (updating GOT entry)", .{}); | 1202 | log.debug(" (updating GOT entry)", .{}); |
| 1145 | const got_target = SymbolWithLoc{ .sym_index = atom.getSymbolIndex().?, .file = null }; | 1203 | const got_target = SymbolWithLoc{ .sym_index = atom.getSymbolIndex().?, .file = null }; |
| 1146 | const got_atom = self.getGotAtomForSymbol(got_target).?; | 1204 | const got_atom_index = self.getGotAtomIndexForSymbol(got_target).?; |
| 1147 | self.markRelocsDirtyByTarget(got_target); | 1205 | self.markRelocsDirtyByTarget(got_target); |
| 1148 | try self.writePtrWidthAtom(got_atom); | 1206 | try self.writePtrWidthAtom(got_atom_index); |
| 1149 | } | 1207 | } |
| 1150 | } else if (code_len < atom.size) { | 1208 | } else if (code_len < atom.size) { |
| 1151 | self.shrinkAtom(atom, code_len); | 1209 | self.shrinkAtom(atom_index, code_len); |
| 1152 | } | 1210 | } |
| 1153 | atom.size = code_len; | 1211 | self.getAtomPtr(atom_index).size = code_len; |
| 1154 | } else { | 1212 | } else { |
| 1155 | const sym = atom.getSymbolPtr(self); | 1213 | const sym = atom.getSymbolPtr(self); |
| 1156 | try self.setSymbolName(sym, decl_name); | 1214 | try self.setSymbolName(sym, decl_name); |
| 1157 | sym.section_number = @intToEnum(coff.SectionNumber, sect_index + 1); | 1215 | sym.section_number = @intToEnum(coff.SectionNumber, sect_index + 1); |
| 1158 | sym.type = .{ .complex_type = complex_type, .base_type = .NULL }; | 1216 | sym.type = .{ .complex_type = complex_type, .base_type = .NULL }; |
| 1159 | | 1217 | |
| 1160 | const vaddr = try self.allocateAtom(atom, code_len, required_alignment); | 1218 | const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment); |
| 1161 | errdefer self.freeAtom(atom); | 1219 | errdefer self.freeAtom(atom_index); |
| 1162 | log.debug("allocated atom for {s} at 0x{x}", .{ decl_name, vaddr }); | 1220 | log.debug("allocated atom for {s} at 0x{x}", .{ decl_name, vaddr }); |
| 1163 | atom.size = code_len; | 1221 | self.getAtomPtr(atom_index).size = code_len; |
| 1164 | sym.value = vaddr; | 1222 | sym.value = vaddr; |
| 1165 | | 1223 | |
| 1166 | const got_target = SymbolWithLoc{ .sym_index = atom.getSymbolIndex().?, .file = null }; | 1224 | const got_target = SymbolWithLoc{ .sym_index = atom.getSymbolIndex().?, .file = null }; |
| 1167 | const got_index = try self.allocateGotEntry(got_target); | 1225 | const got_index = try self.allocateGotEntry(got_target); |
| 1168 | const got_atom = try self.createGotAtom(got_target); | 1226 | const got_atom_index = try self.createGotAtom(got_target); |
| | 1227 | const got_atom = self.getAtom(got_atom_index); |
| 1169 | self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; | 1228 | self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; |
| 1170 | try self.writePtrWidthAtom(got_atom); | 1229 | try self.writePtrWidthAtom(got_atom_index); |
| 1171 | } | 1230 | } |
| 1172 | | 1231 | |
| 1173 | self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); | 1232 | self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); |
| 1174 | try self.writeAtom(atom, code); | 1233 | try self.writeAtom(atom_index, code); |
| 1175 | } | | |
| 1176 | | | |
| 1177 | fn freeRelocationsForAtom(self: *Coff, atom: *Atom) void { | | |
| 1178 | var removed_relocs = self.relocs.fetchRemove(atom); | | |
| 1179 | if (removed_relocs) |*relocs| relocs.value.deinit(self.base.allocator); | | |
| 1180 | var removed_base_relocs = self.base_relocs.fetchRemove(atom); | | |
| 1181 | if (removed_base_relocs) |*base_relocs| base_relocs.value.deinit(self.base.allocator); | | |
| 1182 | } | 1234 | } |
| 1183 | | 1235 | |
| 1184 | fn freeUnnamedConsts(self: *Coff, decl_index: Module.Decl.Index) void { | 1236 | fn freeUnnamedConsts(self: *Coff, decl_index: Module.Decl.Index) void { |
| 1185 | const gpa = self.base.allocator; | 1237 | const gpa = self.base.allocator; |
| 1186 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return; | 1238 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return; |
| 1187 | for (unnamed_consts.items) |atom| { | 1239 | for (unnamed_consts.items) |atom_index| { |
| 1188 | self.freeAtom(atom); | 1240 | self.freeAtom(atom_index); |
| 1189 | } | 1241 | } |
| 1190 | unnamed_consts.clearAndFree(gpa); | 1242 | unnamed_consts.clearAndFree(gpa); |
| 1191 | } | 1243 | } |
| ... | @@ -1200,11 +1252,11 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { | ... | @@ -1200,11 +1252,11 @@ pub fn freeDecl(self: *Coff, decl_index: Module.Decl.Index) void { |
| 1200 | | 1252 | |
| 1201 | log.debug("freeDecl {*}", .{decl}); | 1253 | log.debug("freeDecl {*}", .{decl}); |
| 1202 | | 1254 | |
| 1203 | if (self.decls.fetchRemove(decl_index)) |kv| { | 1255 | if (self.decls.fetchRemove(decl_index)) |const_kv| { |
| 1204 | if (kv.value) |_| { | 1256 | var kv = const_kv; |
| 1205 | self.freeAtom(&decl.link.coff); | 1257 | self.freeAtom(kv.value.atom); |
| 1206 | self.freeUnnamedConsts(decl_index); | 1258 | self.freeUnnamedConsts(decl_index); |
| 1207 | } | 1259 | kv.value.exports.deinit(self.base.allocator); |
| 1208 | } | 1260 | } |
| 1209 | } | 1261 | } |
| 1210 | | 1262 | |
| ... | @@ -1257,16 +1309,10 @@ pub fn updateDeclExports( | ... | @@ -1257,16 +1309,10 @@ pub fn updateDeclExports( |
| 1257 | const gpa = self.base.allocator; | 1309 | const gpa = self.base.allocator; |
| 1258 | | 1310 | |
| 1259 | const decl = module.declPtr(decl_index); | 1311 | const decl = module.declPtr(decl_index); |
| 1260 | const atom = &decl.link.coff; | 1312 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 1261 | | 1313 | const atom = self.getAtom(atom_index); |
| 1262 | if (atom.getSymbolIndex() == null) return; | | |
| 1263 | | | |
| 1264 | const gop = try self.decls.getOrPut(gpa, decl_index); | | |
| 1265 | if (!gop.found_existing) { | | |
| 1266 | gop.value_ptr.* = self.getDeclOutputSection(decl); | | |
| 1267 | } | | |
| 1268 | | | |
| 1269 | const decl_sym = atom.getSymbol(self); | 1314 | const decl_sym = atom.getSymbol(self); |
| | 1315 | const decl_metadata = self.decls.getPtr(decl_index).?; |
| 1270 | | 1316 | |
| 1271 | for (exports) |exp| { | 1317 | for (exports) |exp| { |
| 1272 | log.debug("adding new export '{s}'", .{exp.options.name}); | 1318 | log.debug("adding new export '{s}'", .{exp.options.name}); |
| ... | @@ -1301,9 +1347,9 @@ pub fn updateDeclExports( | ... | @@ -1301,9 +1347,9 @@ pub fn updateDeclExports( |
| 1301 | continue; | 1347 | continue; |
| 1302 | } | 1348 | } |
| 1303 | | 1349 | |
| 1304 | const sym_index = exp.link.coff.sym_index orelse blk: { | 1350 | const sym_index = decl_metadata.getExport(self, exp.options.name) orelse blk: { |
| 1305 | const sym_index = try self.allocateSymbol(); | 1351 | const sym_index = try self.allocateSymbol(); |
| 1306 | exp.link.coff.sym_index = sym_index; | 1352 | try decl_metadata.exports.append(gpa, sym_index); |
| 1307 | break :blk sym_index; | 1353 | break :blk sym_index; |
| 1308 | }; | 1354 | }; |
| 1309 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 1355 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| ... | @@ -1326,16 +1372,15 @@ pub fn updateDeclExports( | ... | @@ -1326,16 +1372,15 @@ pub fn updateDeclExports( |
| 1326 | } | 1372 | } |
| 1327 | } | 1373 | } |
| 1328 | | 1374 | |
| 1329 | pub fn deleteExport(self: *Coff, exp: Export) void { | 1375 | pub fn deleteDeclExport(self: *Coff, decl_index: Module.Decl.Index, name: []const u8) void { |
| 1330 | if (self.llvm_object) |_| return; | 1376 | if (self.llvm_object) |_| return; |
| 1331 | const sym_index = exp.sym_index orelse return; | 1377 | const metadata = self.decls.getPtr(decl_index) orelse return; |
| | 1378 | const sym_index = metadata.getExportPtr(self, name) orelse return; |
| 1332 | | 1379 | |
| 1333 | const gpa = self.base.allocator; | 1380 | const gpa = self.base.allocator; |
| 1334 | | 1381 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index.*, .file = null }; |
| 1335 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | | |
| 1336 | const sym = self.getSymbolPtr(sym_loc); | 1382 | const sym = self.getSymbolPtr(sym_loc); |
| 1337 | const sym_name = self.getSymbolName(sym_loc); | 1383 | log.debug("deleting export '{s}'", .{name}); |
| 1338 | log.debug("deleting export '{s}'", .{sym_name}); | | |
| 1339 | assert(sym.storage_class == .EXTERNAL and sym.section_number != .UNDEFINED); | 1384 | assert(sym.storage_class == .EXTERNAL and sym.section_number != .UNDEFINED); |
| 1340 | sym.* = .{ | 1385 | sym.* = .{ |
| 1341 | .name = [_]u8{0} ** 8, | 1386 | .name = [_]u8{0} ** 8, |
| ... | @@ -1345,9 +1390,9 @@ pub fn deleteExport(self: *Coff, exp: Export) void { | ... | @@ -1345,9 +1390,9 @@ pub fn deleteExport(self: *Coff, exp: Export) void { |
| 1345 | .storage_class = .NULL, | 1390 | .storage_class = .NULL, |
| 1346 | .number_of_aux_symbols = 0, | 1391 | .number_of_aux_symbols = 0, |
| 1347 | }; | 1392 | }; |
| 1348 | self.locals_free_list.append(gpa, sym_index) catch {}; | 1393 | self.locals_free_list.append(gpa, sym_index.*) catch {}; |
| 1349 | | 1394 | |
| 1350 | if (self.resolver.fetchRemove(sym_name)) |entry| { | 1395 | if (self.resolver.fetchRemove(name)) |entry| { |
| 1351 | defer gpa.free(entry.key); | 1396 | defer gpa.free(entry.key); |
| 1352 | self.globals_free_list.append(gpa, entry.value) catch {}; | 1397 | self.globals_free_list.append(gpa, entry.value) catch {}; |
| 1353 | self.globals.items[entry.value] = .{ | 1398 | self.globals.items[entry.value] = .{ |
| ... | @@ -1355,6 +1400,8 @@ pub fn deleteExport(self: *Coff, exp: Export) void { | ... | @@ -1355,6 +1400,8 @@ pub fn deleteExport(self: *Coff, exp: Export) void { |
| 1355 | .file = null, | 1400 | .file = null, |
| 1356 | }; | 1401 | }; |
| 1357 | } | 1402 | } |
| | 1403 | |
| | 1404 | sym_index.* = 0; |
| 1358 | } | 1405 | } |
| 1359 | | 1406 | |
| 1360 | fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void { | 1407 | fn resolveGlobalSymbol(self: *Coff, current: SymbolWithLoc) !void { |
| ... | @@ -1419,9 +1466,10 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -1419,9 +1466,10 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 1419 | if (self.imports_table.contains(global)) continue; | 1466 | if (self.imports_table.contains(global)) continue; |
| 1420 | | 1467 | |
| 1421 | const import_index = try self.allocateImportEntry(global); | 1468 | const import_index = try self.allocateImportEntry(global); |
| 1422 | const import_atom = try self.createImportAtom(); | 1469 | const import_atom_index = try self.createImportAtom(); |
| | 1470 | const import_atom = self.getAtom(import_atom_index); |
| 1423 | self.imports.items[import_index].sym_index = import_atom.getSymbolIndex().?; | 1471 | self.imports.items[import_index].sym_index = import_atom.getSymbolIndex().?; |
| 1424 | try self.writePtrWidthAtom(import_atom); | 1472 | try self.writePtrWidthAtom(import_atom_index); |
| 1425 | } | 1473 | } |
| 1426 | | 1474 | |
| 1427 | if (build_options.enable_logging) { | 1475 | if (build_options.enable_logging) { |
| ... | @@ -1455,22 +1503,14 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -1455,22 +1503,14 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 1455 | } | 1503 | } |
| 1456 | } | 1504 | } |
| 1457 | | 1505 | |
| 1458 | pub fn getDeclVAddr( | 1506 | pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link.File.RelocInfo) !u64 { |
| 1459 | self: *Coff, | | |
| 1460 | decl_index: Module.Decl.Index, | | |
| 1461 | reloc_info: link.File.RelocInfo, | | |
| 1462 | ) !u64 { | | |
| 1463 | const mod = self.base.options.module.?; | | |
| 1464 | const decl = mod.declPtr(decl_index); | | |
| 1465 | | | |
| 1466 | assert(self.llvm_object == null); | 1507 | assert(self.llvm_object == null); |
| 1467 | | 1508 | |
| 1468 | try decl.link.coff.ensureInitialized(self); | 1509 | const this_atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 1469 | const sym_index = decl.link.coff.getSymbolIndex().?; | 1510 | const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?; |
| 1470 | | 1511 | const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?; |
| 1471 | const atom = self.getAtomForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?; | | |
| 1472 | const target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 1512 | const target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 1473 | try atom.addRelocation(self, .{ | 1513 | try Atom.addRelocation(self, atom_index, .{ |
| 1474 | .type = .direct, | 1514 | .type = .direct, |
| 1475 | .target = target, | 1515 | .target = target, |
| 1476 | .offset = @intCast(u32, reloc_info.offset), | 1516 | .offset = @intCast(u32, reloc_info.offset), |
| ... | @@ -1478,7 +1518,7 @@ pub fn getDeclVAddr( | ... | @@ -1478,7 +1518,7 @@ pub fn getDeclVAddr( |
| 1478 | .pcrel = false, | 1518 | .pcrel = false, |
| 1479 | .length = 3, | 1519 | .length = 3, |
| 1480 | }); | 1520 | }); |
| 1481 | try atom.addBaseRelocation(self, @intCast(u32, reloc_info.offset)); | 1521 | try Atom.addBaseRelocation(self, atom_index, @intCast(u32, reloc_info.offset)); |
| 1482 | | 1522 | |
| 1483 | return 0; | 1523 | return 0; |
| 1484 | } | 1524 | } |
| ... | @@ -1529,7 +1569,8 @@ fn writeBaseRelocations(self: *Coff) !void { | ... | @@ -1529,7 +1569,8 @@ fn writeBaseRelocations(self: *Coff) !void { |
| 1529 | | 1569 | |
| 1530 | var it = self.base_relocs.iterator(); | 1570 | var it = self.base_relocs.iterator(); |
| 1531 | while (it.next()) |entry| { | 1571 | while (it.next()) |entry| { |
| 1532 | const atom = entry.key_ptr.*; | 1572 | const atom_index = entry.key_ptr.*; |
| | 1573 | const atom = self.getAtom(atom_index); |
| 1533 | const offsets = entry.value_ptr.*; | 1574 | const offsets = entry.value_ptr.*; |
| 1534 | | 1575 | |
| 1535 | for (offsets.items) |offset| { | 1576 | for (offsets.items) |offset| { |
| ... | @@ -1613,7 +1654,8 @@ fn writeImportTable(self: *Coff) !void { | ... | @@ -1613,7 +1654,8 @@ fn writeImportTable(self: *Coff) !void { |
| 1613 | const gpa = self.base.allocator; | 1654 | const gpa = self.base.allocator; |
| 1614 | | 1655 | |
| 1615 | const section = self.sections.get(self.idata_section_index.?); | 1656 | const section = self.sections.get(self.idata_section_index.?); |
| 1616 | const last_atom = section.last_atom orelse return; | 1657 | const last_atom_index = section.last_atom_index orelse return; |
| | 1658 | const last_atom = self.getAtom(last_atom_index); |
| 1617 | | 1659 | |
| 1618 | const iat_rva = section.header.virtual_address; | 1660 | const iat_rva = section.header.virtual_address; |
| 1619 | const iat_size = last_atom.getSymbol(self).value + last_atom.size * 2 - iat_rva; // account for sentinel zero pointer | 1661 | const iat_size = last_atom.getSymbol(self).value + last_atom.size * 2 - iat_rva; // account for sentinel zero pointer |
| ... | @@ -2051,27 +2093,37 @@ pub fn getOrPutGlobalPtr(self: *Coff, name: []const u8) !GetOrPutGlobalPtrResult | ... | @@ -2051,27 +2093,37 @@ pub fn getOrPutGlobalPtr(self: *Coff, name: []const u8) !GetOrPutGlobalPtrResult |
| 2051 | return GetOrPutGlobalPtrResult{ .found_existing = false, .value_ptr = ptr }; | 2093 | return GetOrPutGlobalPtrResult{ .found_existing = false, .value_ptr = ptr }; |
| 2052 | } | 2094 | } |
| 2053 | | 2095 | |
| | 2096 | pub fn getAtom(self: *const Coff, atom_index: Atom.Index) Atom { |
| | 2097 | assert(atom_index < self.atoms.items.len); |
| | 2098 | return self.atoms.items[atom_index]; |
| | 2099 | } |
| | 2100 | |
| | 2101 | pub fn getAtomPtr(self: *Coff, atom_index: Atom.Index) *Atom { |
| | 2102 | assert(atom_index < self.atoms.items.len); |
| | 2103 | return &self.atoms.items[atom_index]; |
| | 2104 | } |
| | 2105 | |
| 2054 | /// Returns atom if there is an atom referenced by the symbol described by `sym_loc` descriptor. | 2106 | /// Returns atom if there is an atom referenced by the symbol described by `sym_loc` descriptor. |
| 2055 | /// Returns null on failure. | 2107 | /// Returns null on failure. |
| 2056 | pub fn getAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { | 2108 | pub fn getAtomIndexForSymbol(self: *const Coff, sym_loc: SymbolWithLoc) ?Atom.Index { |
| 2057 | assert(sym_loc.file == null); // TODO linking with object files | 2109 | assert(sym_loc.file == null); // TODO linking with object files |
| 2058 | return self.atom_by_index_table.get(sym_loc.sym_index); | 2110 | return self.atom_by_index_table.get(sym_loc.sym_index); |
| 2059 | } | 2111 | } |
| 2060 | | 2112 | |
| 2061 | /// Returns GOT atom that references `sym_loc` if one exists. | 2113 | /// Returns GOT atom that references `sym_loc` if one exists. |
| 2062 | /// Returns null otherwise. | 2114 | /// Returns null otherwise. |
| 2063 | pub fn getGotAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { | 2115 | pub fn getGotAtomIndexForSymbol(self: *const Coff, sym_loc: SymbolWithLoc) ?Atom.Index { |
| 2064 | const got_index = self.got_entries_table.get(sym_loc) orelse return null; | 2116 | const got_index = self.got_entries_table.get(sym_loc) orelse return null; |
| 2065 | const got_entry = self.got_entries.items[got_index]; | 2117 | const got_entry = self.got_entries.items[got_index]; |
| 2066 | return self.getAtomForSymbol(.{ .sym_index = got_entry.sym_index, .file = null }); | 2118 | return self.getAtomIndexForSymbol(.{ .sym_index = got_entry.sym_index, .file = null }); |
| 2067 | } | 2119 | } |
| 2068 | | 2120 | |
| 2069 | /// Returns import atom that references `sym_loc` if one exists. | 2121 | /// Returns import atom that references `sym_loc` if one exists. |
| 2070 | /// Returns null otherwise. | 2122 | /// Returns null otherwise. |
| 2071 | pub fn getImportAtomForSymbol(self: *Coff, sym_loc: SymbolWithLoc) ?*Atom { | 2123 | pub fn getImportAtomIndexForSymbol(self: *const Coff, sym_loc: SymbolWithLoc) ?Atom.Index { |
| 2072 | const imports_index = self.imports_table.get(sym_loc) orelse return null; | 2124 | const imports_index = self.imports_table.get(sym_loc) orelse return null; |
| 2073 | const imports_entry = self.imports.items[imports_index]; | 2125 | const imports_entry = self.imports.items[imports_index]; |
| 2074 | return self.getAtomForSymbol(.{ .sym_index = imports_entry.sym_index, .file = null }); | 2126 | return self.getAtomIndexForSymbol(.{ .sym_index = imports_entry.sym_index, .file = null }); |
| 2075 | } | 2127 | } |
| 2076 | | 2128 | |
| 2077 | fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !void { | 2129 | fn setSectionName(self: *Coff, header: *coff.SectionHeader, name: []const u8) !void { |