mirror of
https://github.com/ziglang/zig.git
synced 2026-01-05 21:13:24 +00:00
elf: move sections in segments that need moving only
This commit is contained in:
parent
9a15c3e1a1
commit
0aa24ac2e3
@ -570,8 +570,6 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64, min_align
|
||||
const slice = self.sections.slice();
|
||||
const shdr = &slice.items(.shdr)[shdr_index];
|
||||
assert(shdr.sh_flags & elf.SHF_ALLOC != 0);
|
||||
const phndx = slice.items(.phndx)[shdr_index];
|
||||
const maybe_phdr = if (phndx) |ndx| &self.phdrs.items[ndx] else null;
|
||||
|
||||
log.debug("allocated size {x} of {s}, needed size {x}", .{
|
||||
self.allocatedSize(shdr.sh_offset),
|
||||
@ -598,11 +596,9 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64, min_align
|
||||
if (amt != existing_size) return error.InputOutput;
|
||||
|
||||
shdr.sh_offset = new_offset;
|
||||
if (maybe_phdr) |phdr| phdr.p_offset = new_offset;
|
||||
} else if (shdr.sh_offset + allocated_size == std.math.maxInt(u64)) {
|
||||
try self.base.file.?.setEndPos(shdr.sh_offset + needed_size);
|
||||
}
|
||||
if (maybe_phdr) |phdr| phdr.p_filesz = needed_size;
|
||||
}
|
||||
shdr.sh_size = needed_size;
|
||||
self.markDirty(shdr_index);
|
||||
@ -3890,57 +3886,70 @@ pub fn allocateAllocSections(self: *Elf) !void {
|
||||
}
|
||||
|
||||
const first = slice.items(.shdr)[cover.items[0]];
|
||||
var new_offset = try self.findFreeSpace(filesz, @"align");
|
||||
const phndx = self.getPhdr(.{ .type = elf.PT_LOAD, .flags = shdrToPhdrFlags(first.sh_flags) }).?;
|
||||
const phdr = &self.phdrs.items[phndx];
|
||||
phdr.p_offset = new_offset;
|
||||
phdr.p_vaddr = first.sh_addr;
|
||||
phdr.p_paddr = first.sh_addr;
|
||||
phdr.p_memsz = memsz;
|
||||
phdr.p_filesz = filesz;
|
||||
phdr.p_align = @"align";
|
||||
const allocated_size = self.allocatedSize(phdr.p_offset);
|
||||
if (filesz > allocated_size) {
|
||||
const old_offset = phdr.p_offset;
|
||||
phdr.p_offset = 0;
|
||||
var new_offset = try self.findFreeSpace(filesz, @"align");
|
||||
phdr.p_offset = new_offset;
|
||||
|
||||
for (cover.items) |shndx| {
|
||||
const shdr = &slice.items(.shdr)[shndx];
|
||||
slice.items(.phndx)[shndx] = phndx;
|
||||
if (shdr.sh_type == elf.SHT_NOBITS) {
|
||||
shdr.sh_offset = 0;
|
||||
continue;
|
||||
}
|
||||
new_offset = alignment.@"align"(shndx, shdr.sh_addralign, new_offset);
|
||||
log.debug("moving phdr({d}) from 0x{x} to 0x{x}", .{ phndx, old_offset, new_offset });
|
||||
|
||||
for (cover.items) |shndx| {
|
||||
const shdr = &slice.items(.shdr)[shndx];
|
||||
slice.items(.phndx)[shndx] = phndx;
|
||||
if (shdr.sh_type == elf.SHT_NOBITS) {
|
||||
shdr.sh_offset = 0;
|
||||
continue;
|
||||
}
|
||||
new_offset = alignment.@"align"(shndx, shdr.sh_addralign, new_offset);
|
||||
|
||||
if (self.zigObjectPtr()) |zo| blk: {
|
||||
const existing_size = for ([_]?Symbol.Index{
|
||||
zo.text_index,
|
||||
zo.rodata_index,
|
||||
zo.data_relro_index,
|
||||
zo.data_index,
|
||||
zo.tdata_index,
|
||||
zo.eh_frame_index,
|
||||
}) |maybe_sym_index| {
|
||||
const sect_sym_index = maybe_sym_index orelse continue;
|
||||
const sect_atom_ptr = zo.symbol(sect_sym_index).atom(self).?;
|
||||
if (sect_atom_ptr.output_section_index != shndx) continue;
|
||||
break sect_atom_ptr.size;
|
||||
} else break :blk;
|
||||
log.debug("moving {s} from 0x{x} to 0x{x}", .{
|
||||
self.getShString(shdr.sh_name),
|
||||
shdr.sh_offset,
|
||||
new_offset,
|
||||
});
|
||||
const amt = try self.base.file.?.copyRangeAll(
|
||||
shdr.sh_offset,
|
||||
self.base.file.?,
|
||||
new_offset,
|
||||
existing_size,
|
||||
);
|
||||
if (amt != existing_size) return error.InputOutput;
|
||||
}
|
||||
|
||||
shdr.sh_offset = new_offset;
|
||||
new_offset += shdr.sh_size;
|
||||
if (shdr.sh_offset > 0) {
|
||||
// Get size actually commited to the output file.
|
||||
const existing_size = if (self.zigObjectPtr()) |zo| for ([_]?Symbol.Index{
|
||||
zo.text_index,
|
||||
zo.rodata_index,
|
||||
zo.data_relro_index,
|
||||
zo.data_index,
|
||||
zo.tdata_index,
|
||||
zo.eh_frame_index,
|
||||
}) |maybe_sym_index| {
|
||||
const sect_sym_index = maybe_sym_index orelse continue;
|
||||
const sect_atom_ptr = zo.symbol(sect_sym_index).atom(self).?;
|
||||
if (sect_atom_ptr.output_section_index != shndx) continue;
|
||||
break sect_atom_ptr.size;
|
||||
} else 0 else 0 + if (!slice.items(.atom_list_2)[shndx].dirty)
|
||||
slice.items(.atom_list_2)[shndx].size
|
||||
else
|
||||
0;
|
||||
const amt = try self.base.file.?.copyRangeAll(
|
||||
shdr.sh_offset,
|
||||
self.base.file.?,
|
||||
new_offset,
|
||||
existing_size,
|
||||
);
|
||||
if (amt != existing_size) return error.InputOutput;
|
||||
}
|
||||
|
||||
shdr.sh_offset = new_offset;
|
||||
new_offset += shdr.sh_size;
|
||||
}
|
||||
}
|
||||
|
||||
phdr.p_vaddr = first.sh_addr;
|
||||
phdr.p_paddr = first.sh_addr;
|
||||
phdr.p_memsz = memsz;
|
||||
phdr.p_filesz = filesz;
|
||||
phdr.p_align = @"align";
|
||||
|
||||
addr = mem.alignForward(u64, addr, self.page_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -336,8 +336,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
|
||||
const atom_ptr = self.atom(sym.ref.index).?;
|
||||
if (!atom_ptr.alive) continue;
|
||||
|
||||
log.debug("parsing relocs in {s}", .{sym.name(elf_file)});
|
||||
|
||||
const relocs = &self.relocs.items[atom_ptr.relocsShndx().?];
|
||||
for (sect.units.items) |*unit| {
|
||||
try relocs.ensureUnusedCapacity(gpa, unit.cross_unit_relocs.items.len +
|
||||
@ -350,12 +348,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
|
||||
else
|
||||
0));
|
||||
const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
|
||||
log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
|
||||
self.symbol(sym_index).name(elf_file),
|
||||
r_offset,
|
||||
r_addend,
|
||||
relocation.fmtRelocType(r_type, cpu_arch),
|
||||
});
|
||||
atom_ptr.addRelocAssumeCapacity(.{
|
||||
.r_offset = r_offset,
|
||||
.r_addend = r_addend,
|
||||
@ -384,12 +376,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
|
||||
else
|
||||
0));
|
||||
const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
|
||||
log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
|
||||
self.symbol(target_sym_index).name(elf_file),
|
||||
r_offset,
|
||||
r_addend,
|
||||
relocation.fmtRelocType(r_type, cpu_arch),
|
||||
});
|
||||
atom_ptr.addRelocAssumeCapacity(.{
|
||||
.r_offset = r_offset,
|
||||
.r_addend = r_addend,
|
||||
@ -410,12 +396,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
|
||||
else
|
||||
0));
|
||||
const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
|
||||
log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
|
||||
self.symbol(sym_index).name(elf_file),
|
||||
r_offset,
|
||||
r_addend,
|
||||
relocation.fmtRelocType(r_type, cpu_arch),
|
||||
});
|
||||
atom_ptr.addRelocAssumeCapacity(.{
|
||||
.r_offset = r_offset,
|
||||
.r_addend = r_addend,
|
||||
@ -430,12 +410,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
|
||||
else
|
||||
0));
|
||||
const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
|
||||
log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
|
||||
self.symbol(sym_index).name(elf_file),
|
||||
r_offset,
|
||||
r_addend,
|
||||
relocation.fmtRelocType(r_type, cpu_arch),
|
||||
});
|
||||
atom_ptr.addRelocAssumeCapacity(.{
|
||||
.r_offset = r_offset,
|
||||
.r_addend = r_addend,
|
||||
@ -464,12 +438,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
|
||||
else
|
||||
0));
|
||||
const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
|
||||
log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
|
||||
self.symbol(target_sym_index).name(elf_file),
|
||||
r_offset,
|
||||
r_addend,
|
||||
relocation.fmtRelocType(r_type, cpu_arch),
|
||||
});
|
||||
atom_ptr.addRelocAssumeCapacity(.{
|
||||
.r_offset = r_offset,
|
||||
.r_addend = r_addend,
|
||||
@ -481,12 +449,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
|
||||
const r_offset = entry_off + reloc.source_off;
|
||||
const r_addend: i64 = @intCast(reloc.target_off);
|
||||
const r_type = relocation.dwarf.externalRelocType(target_sym.*, sect_index, dwarf.address_size, cpu_arch);
|
||||
log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
|
||||
target_sym.name(elf_file),
|
||||
r_offset,
|
||||
r_addend,
|
||||
relocation.fmtRelocType(r_type, cpu_arch),
|
||||
});
|
||||
atom_ptr.addRelocAssumeCapacity(.{
|
||||
.r_offset = r_offset,
|
||||
.r_addend = r_addend,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user