mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-09 07:08:59 +00:00
Elf: keep the logic for updates but condition on hcs
This commit is contained in:
parent
defb309013
commit
b1930a3b57
1 changed files with 62 additions and 2 deletions
|
|
@ -2097,6 +2097,7 @@ fn growTextBlock(self: *Elf, block_list: *TextBlockList, text_block: *TextBlock,
|
||||||
fn allocateTextBlock(self: *Elf, block_list: *TextBlockList, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 {
|
fn allocateTextBlock(self: *Elf, block_list: *TextBlockList, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 {
|
||||||
const phdr = &self.program_headers.items[block_list.phdr_index.?];
|
const phdr = &self.program_headers.items[block_list.phdr_index.?];
|
||||||
const shdr = &self.sections.items[block_list.section_index.?];
|
const shdr = &self.sections.items[block_list.section_index.?];
|
||||||
|
const new_block_ideal_capacity = padToIdeal(new_block_size);
|
||||||
|
|
||||||
// We use these to indicate our intention to update metadata, placing the new block,
|
// We use these to indicate our intention to update metadata, placing the new block,
|
||||||
// and possibly removing a free list node.
|
// and possibly removing a free list node.
|
||||||
|
|
@ -2109,7 +2110,42 @@ fn allocateTextBlock(self: *Elf, block_list: *TextBlockList, text_block: *TextBl
|
||||||
// First we look for an appropriately sized free list node.
|
// First we look for an appropriately sized free list node.
|
||||||
// The list is unordered. We'll just take the first thing that works.
|
// The list is unordered. We'll just take the first thing that works.
|
||||||
const vaddr = blk: {
|
const vaddr = blk: {
|
||||||
if (block_list.last_block) |last| {
|
var i: usize = if (self.base.child_pid == null) 0 else block_list.free_list.items.len;
|
||||||
|
while (i < block_list.free_list.items.len) {
|
||||||
|
const big_block = block_list.free_list.items[i];
|
||||||
|
// We now have a pointer to a live text block that has too much capacity.
|
||||||
|
// Is it enough that we could fit this new text block?
|
||||||
|
const sym = self.local_symbols.items[big_block.local_sym_index];
|
||||||
|
const capacity = big_block.capacity(self.*);
|
||||||
|
const ideal_capacity = padToIdeal(capacity);
|
||||||
|
const ideal_capacity_end_vaddr = sym.st_value + ideal_capacity;
|
||||||
|
const capacity_end_vaddr = sym.st_value + capacity;
|
||||||
|
const new_start_vaddr_unaligned = capacity_end_vaddr - new_block_ideal_capacity;
|
||||||
|
const new_start_vaddr = mem.alignBackwardGeneric(u64, new_start_vaddr_unaligned, alignment);
|
||||||
|
if (new_start_vaddr < ideal_capacity_end_vaddr) {
|
||||||
|
// Additional bookkeeping here to notice if this free list node
|
||||||
|
// should be deleted because the block that it points to has grown to take up
|
||||||
|
// more of the extra capacity.
|
||||||
|
if (!big_block.freeListEligible(self.*)) {
|
||||||
|
_ = block_list.free_list.swapRemove(i);
|
||||||
|
} else {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// At this point we know that we will place the new block here. But the
|
||||||
|
// remaining question is whether there is still yet enough capacity left
|
||||||
|
// over for there to still be a free list node.
|
||||||
|
const remaining_capacity = new_start_vaddr - ideal_capacity_end_vaddr;
|
||||||
|
const keep_free_list_node = remaining_capacity >= min_text_capacity;
|
||||||
|
|
||||||
|
// Set up the metadata to be updated, after errors are no longer possible.
|
||||||
|
block_placement = big_block;
|
||||||
|
if (!keep_free_list_node) {
|
||||||
|
free_list_removal = i;
|
||||||
|
}
|
||||||
|
break :blk new_start_vaddr;
|
||||||
|
} else if (block_list.last_block) |last| {
|
||||||
const sym = self.local_symbols.items[last.local_sym_index];
|
const sym = self.local_symbols.items[last.local_sym_index];
|
||||||
const ideal_capacity = padToIdeal(sym.st_size);
|
const ideal_capacity = padToIdeal(sym.st_size);
|
||||||
const ideal_capacity_end_vaddr = sym.st_value + ideal_capacity;
|
const ideal_capacity_end_vaddr = sym.st_value + ideal_capacity;
|
||||||
|
|
@ -2282,7 +2318,31 @@ fn updateDeclCode(self: *Elf, decl: *Module.Decl, code: []const u8, stt_bits: u8
|
||||||
|
|
||||||
assert(decl.link.elf.local_sym_index != 0); // Caller forgot to allocateDeclIndexes()
|
assert(decl.link.elf.local_sym_index != 0); // Caller forgot to allocateDeclIndexes()
|
||||||
const local_sym = &self.local_symbols.items[decl.link.elf.local_sym_index];
|
const local_sym = &self.local_symbols.items[decl.link.elf.local_sym_index];
|
||||||
{
|
if (local_sym.st_size != 0 and self.base.child_pid == null) {
|
||||||
|
const capacity = decl.link.elf.capacity(self.*);
|
||||||
|
const need_realloc = code.len > capacity or
|
||||||
|
!mem.isAlignedGeneric(u64, local_sym.st_value, required_alignment);
|
||||||
|
if (need_realloc) {
|
||||||
|
const vaddr = try self.growTextBlock(block_list, &decl.link.elf, code.len, required_alignment);
|
||||||
|
log.debug("growing {s} from 0x{x} to 0x{x}", .{ decl.name, local_sym.st_value, vaddr });
|
||||||
|
if (vaddr != local_sym.st_value) {
|
||||||
|
local_sym.st_value = vaddr;
|
||||||
|
|
||||||
|
log.debug(" (writing new offset table entry)", .{});
|
||||||
|
self.offset_table.items[decl.link.elf.offset_table_index] = vaddr;
|
||||||
|
try self.writeOffsetTableEntry(decl.link.elf.offset_table_index);
|
||||||
|
}
|
||||||
|
} else if (code.len < local_sym.st_size) {
|
||||||
|
self.shrinkTextBlock(block_list, &decl.link.elf, code.len);
|
||||||
|
}
|
||||||
|
local_sym.st_size = code.len;
|
||||||
|
local_sym.st_name = try self.updateString(local_sym.st_name, mem.sliceTo(decl.name, 0));
|
||||||
|
local_sym.st_info = (elf.STB_LOCAL << 4) | stt_bits;
|
||||||
|
local_sym.st_other = 0;
|
||||||
|
local_sym.st_shndx = block_list.section_index.?;
|
||||||
|
// TODO this write could be avoided if no fields of the symbol were changed.
|
||||||
|
try self.writeSymbol(decl.link.elf.local_sym_index);
|
||||||
|
} else {
|
||||||
const decl_name = mem.sliceTo(decl.name, 0);
|
const decl_name = mem.sliceTo(decl.name, 0);
|
||||||
const name_str_index = try self.makeString(decl_name);
|
const name_str_index = try self.makeString(decl_name);
|
||||||
const vaddr = try self.allocateTextBlock(block_list, &decl.link.elf, code.len, required_alignment);
|
const vaddr = try self.allocateTextBlock(block_list, &decl.link.elf, code.len, required_alignment);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue