authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-09-30 22:09:44+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-10-09 12:38:11-07:00
log0aa24ac2e3c122ad16d54d640c11f2de6eb2299a
tree3b763b412e9a9139ed781ff44ff4f3641a39387f
parent9a15c3e1a1dc01d04c976ffbdec46b206455634e

elf: move sections in segments that need moving only


2 files changed, 53 insertions(+), 82 deletions(-)

src/link/Elf.zig+53-44
...@@ -570,8 +570,6 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64, min_align...@@ -570,8 +570,6 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64, min_align
570 const slice = self.sections.slice();570 const slice = self.sections.slice();
571 const shdr = &slice.items(.shdr)[shdr_index];571 const shdr = &slice.items(.shdr)[shdr_index];
572 assert(shdr.sh_flags & elf.SHF_ALLOC != 0);572 assert(shdr.sh_flags & elf.SHF_ALLOC != 0);
573 const phndx = slice.items(.phndx)[shdr_index];
574 const maybe_phdr = if (phndx) |ndx| &self.phdrs.items[ndx] else null;
575573
576 log.debug("allocated size {x} of {s}, needed size {x}", .{574 log.debug("allocated size {x} of {s}, needed size {x}", .{
577 self.allocatedSize(shdr.sh_offset),575 self.allocatedSize(shdr.sh_offset),
...@@ -598,11 +596,9 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64, min_align...@@ -598,11 +596,9 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64, min_align
598 if (amt != existing_size) return error.InputOutput;596 if (amt != existing_size) return error.InputOutput;
599597
600 shdr.sh_offset = new_offset;598 shdr.sh_offset = new_offset;
601 if (maybe_phdr) |phdr| phdr.p_offset = new_offset;
602 } else if (shdr.sh_offset + allocated_size == std.math.maxInt(u64)) {599 } else if (shdr.sh_offset + allocated_size == std.math.maxInt(u64)) {
603 try self.base.file.?.setEndPos(shdr.sh_offset + needed_size);600 try self.base.file.?.setEndPos(shdr.sh_offset + needed_size);
604 }601 }
605 if (maybe_phdr) |phdr| phdr.p_filesz = needed_size;
606 }602 }
607 shdr.sh_size = needed_size;603 shdr.sh_size = needed_size;
608 self.markDirty(shdr_index);604 self.markDirty(shdr_index);
...@@ -3890,57 +3886,70 @@ pub fn allocateAllocSections(self: *Elf) !void {...@@ -3890,57 +3886,70 @@ pub fn allocateAllocSections(self: *Elf) !void {
3890 }3886 }
38913887
3892 const first = slice.items(.shdr)[cover.items[0]];3888 const first = slice.items(.shdr)[cover.items[0]];
3893 var new_offset = try self.findFreeSpace(filesz, @"align");
3894 const phndx = self.getPhdr(.{ .type = elf.PT_LOAD, .flags = shdrToPhdrFlags(first.sh_flags) }).?;3889 const phndx = self.getPhdr(.{ .type = elf.PT_LOAD, .flags = shdrToPhdrFlags(first.sh_flags) }).?;
3895 const phdr = &self.phdrs.items[phndx];3890 const phdr = &self.phdrs.items[phndx];
3896 phdr.p_offset = new_offset;3891 const allocated_size = self.allocatedSize(phdr.p_offset);
3897 phdr.p_vaddr = first.sh_addr;3892 if (filesz > allocated_size) {
3898 phdr.p_paddr = first.sh_addr;3893 const old_offset = phdr.p_offset;
3899 phdr.p_memsz = memsz;3894 phdr.p_offset = 0;
3900 phdr.p_filesz = filesz;3895 var new_offset = try self.findFreeSpace(filesz, @"align");
3901 phdr.p_align = @"align";3896 phdr.p_offset = new_offset;
39023897
3903 for (cover.items) |shndx| {3898 log.debug("moving phdr({d}) from 0x{x} to 0x{x}", .{ phndx, old_offset, new_offset });
3904 const shdr = &slice.items(.shdr)[shndx];3899
3905 slice.items(.phndx)[shndx] = phndx;3900 for (cover.items) |shndx| {
3906 if (shdr.sh_type == elf.SHT_NOBITS) {3901 const shdr = &slice.items(.shdr)[shndx];
3907 shdr.sh_offset = 0;3902 slice.items(.phndx)[shndx] = phndx;
3908 continue;3903 if (shdr.sh_type == elf.SHT_NOBITS) {
3909 }3904 shdr.sh_offset = 0;
3910 new_offset = alignment.@"align"(shndx, shdr.sh_addralign, new_offset);3905 continue;
3906 }
3907 new_offset = alignment.@"align"(shndx, shdr.sh_addralign, new_offset);
39113908
3912 if (self.zigObjectPtr()) |zo| blk: {
3913 const existing_size = for ([_]?Symbol.Index{
3914 zo.text_index,
3915 zo.rodata_index,
3916 zo.data_relro_index,
3917 zo.data_index,
3918 zo.tdata_index,
3919 zo.eh_frame_index,
3920 }) |maybe_sym_index| {
3921 const sect_sym_index = maybe_sym_index orelse continue;
3922 const sect_atom_ptr = zo.symbol(sect_sym_index).atom(self).?;
3923 if (sect_atom_ptr.output_section_index != shndx) continue;
3924 break sect_atom_ptr.size;
3925 } else break :blk;
3926 log.debug("moving {s} from 0x{x} to 0x{x}", .{3909 log.debug("moving {s} from 0x{x} to 0x{x}", .{
3927 self.getShString(shdr.sh_name),3910 self.getShString(shdr.sh_name),
3928 shdr.sh_offset,3911 shdr.sh_offset,
3929 new_offset,3912 new_offset,
3930 });3913 });
3931 const amt = try self.base.file.?.copyRangeAll(
3932 shdr.sh_offset,
3933 self.base.file.?,
3934 new_offset,
3935 existing_size,
3936 );
3937 if (amt != existing_size) return error.InputOutput;
3938 }
39393914
3940 shdr.sh_offset = new_offset;3915 if (shdr.sh_offset > 0) {
3941 new_offset += shdr.sh_size;3916 // Get size actually commited to the output file.
3917 const existing_size = if (self.zigObjectPtr()) |zo| for ([_]?Symbol.Index{
3918 zo.text_index,
3919 zo.rodata_index,
3920 zo.data_relro_index,
3921 zo.data_index,
3922 zo.tdata_index,
3923 zo.eh_frame_index,
3924 }) |maybe_sym_index| {
3925 const sect_sym_index = maybe_sym_index orelse continue;
3926 const sect_atom_ptr = zo.symbol(sect_sym_index).atom(self).?;
3927 if (sect_atom_ptr.output_section_index != shndx) continue;
3928 break sect_atom_ptr.size;
3929 } else 0 else 0 + if (!slice.items(.atom_list_2)[shndx].dirty)
3930 slice.items(.atom_list_2)[shndx].size
3931 else
3932 0;
3933 const amt = try self.base.file.?.copyRangeAll(
3934 shdr.sh_offset,
3935 self.base.file.?,
3936 new_offset,
3937 existing_size,
3938 );
3939 if (amt != existing_size) return error.InputOutput;
3940 }
3941
3942 shdr.sh_offset = new_offset;
3943 new_offset += shdr.sh_size;
3944 }
3942 }3945 }
39433946
3947 phdr.p_vaddr = first.sh_addr;
3948 phdr.p_paddr = first.sh_addr;
3949 phdr.p_memsz = memsz;
3950 phdr.p_filesz = filesz;
3951 phdr.p_align = @"align";
3952
3944 addr = mem.alignForward(u64, addr, self.page_size);3953 addr = mem.alignForward(u64, addr, self.page_size);
3945 }3954 }
3946}3955}
src/link/Elf/ZigObject.zig-38
...@@ -336,8 +336,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -336,8 +336,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
336 const atom_ptr = self.atom(sym.ref.index).?;336 const atom_ptr = self.atom(sym.ref.index).?;
337 if (!atom_ptr.alive) continue;337 if (!atom_ptr.alive) continue;
338338
339 log.debug("parsing relocs in {s}", .{sym.name(elf_file)});
340
341 const relocs = &self.relocs.items[atom_ptr.relocsShndx().?];339 const relocs = &self.relocs.items[atom_ptr.relocsShndx().?];
342 for (sect.units.items) |*unit| {340 for (sect.units.items) |*unit| {
343 try relocs.ensureUnusedCapacity(gpa, unit.cross_unit_relocs.items.len +341 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...@@ -350,12 +348,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
350 else348 else
351 0));349 0));
352 const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);350 const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
353 log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
354 self.symbol(sym_index).name(elf_file),
355 r_offset,
356 r_addend,
357 relocation.fmtRelocType(r_type, cpu_arch),
358 });
359 atom_ptr.addRelocAssumeCapacity(.{351 atom_ptr.addRelocAssumeCapacity(.{
360 .r_offset = r_offset,352 .r_offset = r_offset,
361 .r_addend = r_addend,353 .r_addend = r_addend,
...@@ -384,12 +376,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -384,12 +376,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
384 else376 else
385 0));377 0));
386 const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);378 const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
387 log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
388 self.symbol(target_sym_index).name(elf_file),
389 r_offset,
390 r_addend,
391 relocation.fmtRelocType(r_type, cpu_arch),
392 });
393 atom_ptr.addRelocAssumeCapacity(.{379 atom_ptr.addRelocAssumeCapacity(.{
394 .r_offset = r_offset,380 .r_offset = r_offset,
395 .r_addend = r_addend,381 .r_addend = r_addend,
...@@ -410,12 +396,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -410,12 +396,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
410 else396 else
411 0));397 0));
412 const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);398 const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
413 log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
414 self.symbol(sym_index).name(elf_file),
415 r_offset,
416 r_addend,
417 relocation.fmtRelocType(r_type, cpu_arch),
418 });
419 atom_ptr.addRelocAssumeCapacity(.{399 atom_ptr.addRelocAssumeCapacity(.{
420 .r_offset = r_offset,400 .r_offset = r_offset,
421 .r_addend = r_addend,401 .r_addend = r_addend,
...@@ -430,12 +410,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -430,12 +410,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
430 else410 else
431 0));411 0));
432 const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);412 const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
433 log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
434 self.symbol(sym_index).name(elf_file),
435 r_offset,
436 r_addend,
437 relocation.fmtRelocType(r_type, cpu_arch),
438 });
439 atom_ptr.addRelocAssumeCapacity(.{413 atom_ptr.addRelocAssumeCapacity(.{
440 .r_offset = r_offset,414 .r_offset = r_offset,
441 .r_addend = r_addend,415 .r_addend = r_addend,
...@@ -464,12 +438,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -464,12 +438,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
464 else438 else
465 0));439 0));
466 const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);440 const r_type = relocation.dwarf.crossSectionRelocType(dwarf.format, cpu_arch);
467 log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
468 self.symbol(target_sym_index).name(elf_file),
469 r_offset,
470 r_addend,
471 relocation.fmtRelocType(r_type, cpu_arch),
472 });
473 atom_ptr.addRelocAssumeCapacity(.{441 atom_ptr.addRelocAssumeCapacity(.{
474 .r_offset = r_offset,442 .r_offset = r_offset,
475 .r_addend = r_addend,443 .r_addend = r_addend,
...@@ -481,12 +449,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -481,12 +449,6 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
481 const r_offset = entry_off + reloc.source_off;449 const r_offset = entry_off + reloc.source_off;
482 const r_addend: i64 = @intCast(reloc.target_off);450 const r_addend: i64 = @intCast(reloc.target_off);
483 const r_type = relocation.dwarf.externalRelocType(target_sym.*, sect_index, dwarf.address_size, cpu_arch);451 const r_type = relocation.dwarf.externalRelocType(target_sym.*, sect_index, dwarf.address_size, cpu_arch);
484 log.debug(" {s} <- r_off={x}, r_add={x}, r_type={}", .{
485 target_sym.name(elf_file),
486 r_offset,
487 r_addend,
488 relocation.fmtRelocType(r_type, cpu_arch),
489 });
490 atom_ptr.addRelocAssumeCapacity(.{452 atom_ptr.addRelocAssumeCapacity(.{
491 .r_offset = r_offset,453 .r_offset = r_offset,
492 .r_addend = r_addend,454 .r_addend = r_addend,