| ... | ... | @@ -111,7 +111,7 @@ symbols_free_list: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 111 | 111 | |
| 112 | 112 | phdr_table_dirty: bool = false, |
| 113 | 113 | shdr_table_dirty: bool = false, |
| 114 | | got_dirty: bool = false, |
| 114 | got_addresses_dirty: bool = false, |
| 115 | 115 | |
| 116 | 116 | debug_strtab_dirty: bool = false, |
| 117 | 117 | debug_abbrev_section_dirty: bool = false, |
| ... | ... | @@ -942,7 +942,7 @@ pub fn growAllocSection(self: *Elf, shdr_index: u16, needed_size: u64) !void { |
| 942 | 942 | // and grow. |
| 943 | 943 | { |
| 944 | 944 | const dirty_addr = phdr.p_vaddr + phdr.p_memsz; |
| 945 | | self.got_dirty = for (self.got.entries.items) |entry| { |
| 945 | self.got_addresses_dirty = for (self.got.entries.items) |entry| { |
| 946 | 946 | if (self.symbol(entry.symbol_index).value >= dirty_addr) break true; |
| 947 | 947 | } else false; |
| 948 | 948 | |
| ... | ... | @@ -1333,15 +1333,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1333 | 1333 | } |
| 1334 | 1334 | try self.writeObjects(); |
| 1335 | 1335 | |
| 1336 | | if (self.got_dirty) { |
| 1337 | | const shdr = &self.shdrs.items[self.got_section_index.?]; |
| 1338 | | var buffer = try std.ArrayList(u8).initCapacity(gpa, self.got.size(self)); |
| 1339 | | defer buffer.deinit(); |
| 1340 | | try self.got.writeAllEntries(self, buffer.writer()); |
| 1341 | | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 1342 | | self.got_dirty = false; |
| 1343 | | } |
| 1344 | | |
| 1345 | 1336 | // Look for entry address in objects if not set by the incremental compiler. |
| 1346 | 1337 | if (self.entry_addr == null) { |
| 1347 | 1338 | const entry: ?[]const u8 = entry: { |
| ... | ... | @@ -1541,6 +1532,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1541 | 1532 | assert(!self.shdr_table_dirty); |
| 1542 | 1533 | assert(!self.debug_strtab_dirty); |
| 1543 | 1534 | assert(!self.got.dirty); |
| 1535 | assert(!self.got_addresses_dirty); |
| 1544 | 1536 | } |
| 1545 | 1537 | |
| 1546 | 1538 | const ParseError = error{ |
| ... | ... | @@ -1789,8 +1781,7 @@ fn scanRelocs(self: *Elf) !void { |
| 1789 | 1781 | if (sym.flags.needs_got) { |
| 1790 | 1782 | log.debug("'{s}' needs GOT", .{sym.name(self)}); |
| 1791 | 1783 | // TODO how can we tell we need to write it again, aka the entry is dirty? |
| 1792 | | const gop = try sym.getOrCreateGotEntry(@intCast(sym_index), self); |
| 1793 | | try self.got.writeEntry(self, gop.index); |
| 1784 | _ = try sym.getOrCreateGotEntry(@intCast(sym_index), self); |
| 1794 | 1785 | } |
| 1795 | 1786 | } |
| 1796 | 1787 | } |
| ... | ... | @@ -3472,6 +3463,15 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3472 | 3463 | .p64 => false, |
| 3473 | 3464 | }; |
| 3474 | 3465 | |
| 3466 | if (self.got.entries.items.len > 0 and self.got_section_index == null) { |
| 3467 | self.got_section_index = try self.addSection(.{ |
| 3468 | .name = ".got", |
| 3469 | .type = elf.SHT_PROGBITS, |
| 3470 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| 3471 | .addralign = self.ptrWidthBytes(), |
| 3472 | }); |
| 3473 | } |
| 3474 | |
| 3475 | 3475 | if (self.symtab_section_index == null) { |
| 3476 | 3476 | self.symtab_section_index = try self.addSection(.{ |
| 3477 | 3477 | .name = ".symtab", |
| ... | ... | @@ -3499,9 +3499,18 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3499 | 3499 | } |
| 3500 | 3500 | |
| 3501 | 3501 | fn updateSyntheticSectionSizes(self: *Elf) !void { |
| 3502 | if (self.got_section_index) |index| { |
| 3503 | if (self.got.dirty) { |
| 3504 | try self.growAllocSection(index, self.got.size(self)); |
| 3505 | self.got.dirty = false; |
| 3506 | self.got_addresses_dirty = true; |
| 3507 | } |
| 3508 | } |
| 3509 | |
| 3502 | 3510 | if (self.symtab_section_index != null) { |
| 3503 | 3511 | try self.updateSymtabSize(); |
| 3504 | 3512 | } |
| 3513 | |
| 3505 | 3514 | if (self.strtab_section_index) |index| { |
| 3506 | 3515 | // TODO I don't really this here but we need it to add symbol names from GOT and other synthetic |
| 3507 | 3516 | // sections into .strtab for easier debugging. |
| ... | ... | @@ -3510,6 +3519,7 @@ fn updateSyntheticSectionSizes(self: *Elf) !void { |
| 3510 | 3519 | } |
| 3511 | 3520 | try self.growNonAllocSection(index, self.strtab.buffer.items.len, 1, false); |
| 3512 | 3521 | } |
| 3522 | |
| 3513 | 3523 | if (self.shstrtab_section_index) |index| { |
| 3514 | 3524 | try self.growNonAllocSection(index, self.shstrtab.buffer.items.len, 1, false); |
| 3515 | 3525 | } |
| ... | ... | @@ -3560,14 +3570,25 @@ fn updateSymtabSize(self: *Elf) !void { |
| 3560 | 3570 | } |
| 3561 | 3571 | |
| 3562 | 3572 | fn writeSyntheticSections(self: *Elf) !void { |
| 3573 | if (self.got_addresses_dirty) { |
| 3574 | const shdr = &self.shdrs.items[self.got_section_index.?]; |
| 3575 | var buffer = try std.ArrayList(u8).initCapacity(self.base.allocator, self.got.size(self)); |
| 3576 | defer buffer.deinit(); |
| 3577 | try self.got.writeAllEntries(self, buffer.writer()); |
| 3578 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 3579 | self.got_addresses_dirty = false; |
| 3580 | } |
| 3581 | |
| 3563 | 3582 | if (self.shstrtab_section_index) |index| { |
| 3564 | 3583 | const shdr = self.shdrs.items[index]; |
| 3565 | 3584 | try self.base.file.?.pwriteAll(self.shstrtab.buffer.items, shdr.sh_offset); |
| 3566 | 3585 | } |
| 3586 | |
| 3567 | 3587 | if (self.strtab_section_index) |index| { |
| 3568 | 3588 | const shdr = self.shdrs.items[index]; |
| 3569 | 3589 | try self.base.file.?.pwriteAll(self.strtab.buffer.items, shdr.sh_offset); |
| 3570 | 3590 | } |
| 3591 | |
| 3571 | 3592 | if (self.symtab_section_index) |_| { |
| 3572 | 3593 | try self.writeSymtab(); |
| 3573 | 3594 | } |