authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-23 12:23:10+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-23 17:17:18+02:00
log8960df0c013f83a8adf05ce2ae9a9667d58ef41d
tree23c8f9b7e33321bd91e85f602f4ff3a59a1b4cb6
parent29ebd96818bce4c4f2842d1bb76390247d47e198

elf: encapsulate logic for creating non-alloc shdrs in a helper


1 files changed, 71 insertions(+), 140 deletions(-)

src/link/Elf.zig+71-140
...@@ -458,7 +458,7 @@ fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{OutOfM...@@ -458,7 +458,7 @@ fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{OutOfM
458 try self.shdrs.ensureUnusedCapacity(gpa, 1);458 try self.shdrs.ensureUnusedCapacity(gpa, 1);
459 const sh_name = try self.shstrtab.insert(gpa, opts.name);459 const sh_name = try self.shstrtab.insert(gpa, opts.name);
460 try self.phdr_to_shdr_table.putNoClobber(gpa, index, opts.phdr_index);460 try self.phdr_to_shdr_table.putNoClobber(gpa, index, opts.phdr_index);
461 log.debug("allocating '{s}' in PHDR({d}) from 0x{x} to 0x{x} (0x{x} - 0x{x})", .{461 log.debug("allocating '{s}' in phdr({d}) from 0x{x} to 0x{x} (0x{x} - 0x{x})", .{
462 opts.name,462 opts.name,
463 opts.phdr_index,463 opts.phdr_index,
464 phdr.p_offset,464 phdr.p_offset,
...@@ -482,6 +482,39 @@ fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{OutOfM...@@ -482,6 +482,39 @@ fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{OutOfM
482 return index;482 return index;
483}483}
484484
485const AllocateNonAllocSectionOpts = struct {
486 name: [:0]const u8,
487 size: u64,
488 alignment: u16 = 1,
489 flags: u32 = 0,
490 type: u32 = elf.SHT_PROGBITS,
491 link: u32 = 0,
492 info: u32 = 0,
493 entsize: u64 = 0,
494};
495
496fn allocateNonAllocSection(self: *Elf, opts: AllocateNonAllocSectionOpts) error{OutOfMemory}!u16 {
497 const index = @as(u16, @intCast(self.shdrs.items.len));
498 try self.shdrs.ensureUnusedCapacity(self.base.allocator, 1);
499 const sh_name = try self.shstrtab.insert(self.base.allocator, opts.name);
500 const off = self.findFreeSpace(opts.size, opts.alignment);
501 log.debug("allocating '{s}' from 0x{x} to 0x{x} ", .{ opts.name, off, off + opts.size });
502 self.shdrs.appendAssumeCapacity(.{
503 .sh_name = sh_name,
504 .sh_type = opts.type,
505 .sh_flags = opts.flags,
506 .sh_addr = 0,
507 .sh_offset = off,
508 .sh_size = opts.size,
509 .sh_link = opts.link,
510 .sh_info = opts.info,
511 .sh_addralign = opts.alignment,
512 .sh_entsize = opts.entsize,
513 });
514 self.shdr_table_dirty = true;
515 return index;
516}
517
485pub fn populateMissingMetadata(self: *Elf) !void {518pub fn populateMissingMetadata(self: *Elf) !void {
486 const gpa = self.base.allocator;519 const gpa = self.base.allocator;
487 const small_ptr = switch (self.ptr_width) {520 const small_ptr = switch (self.ptr_width) {
...@@ -592,47 +625,25 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -592,47 +625,25 @@ pub fn populateMissingMetadata(self: *Elf) !void {
592 }625 }
593626
594 if (self.shstrtab_section_index == null) {627 if (self.shstrtab_section_index == null) {
595 self.shstrtab_section_index = @intCast(self.shdrs.items.len);
596 assert(self.shstrtab.buffer.items.len == 0);628 assert(self.shstrtab.buffer.items.len == 0);
597 try self.shstrtab.buffer.append(gpa, 0); // need a 0 at position 0629 try self.shstrtab.buffer.append(gpa, 0); // need a 0 at position 0
598 const off = self.findFreeSpace(self.shstrtab.buffer.items.len, 1);630 self.shstrtab_section_index = try self.allocateNonAllocSection(.{
599 log.debug("found .shstrtab free space 0x{x} to 0x{x}", .{ off, off + self.shstrtab.buffer.items.len });631 .name = ".shstrtab",
600 try self.shdrs.append(gpa, .{632 .size = @intCast(self.shstrtab.buffer.items.len),
601 .sh_name = try self.shstrtab.insert(gpa, ".shstrtab"),633 .type = elf.SHT_STRTAB,
602 .sh_type = elf.SHT_STRTAB,
603 .sh_flags = 0,
604 .sh_addr = 0,
605 .sh_offset = off,
606 .sh_size = self.shstrtab.buffer.items.len,
607 .sh_link = 0,
608 .sh_info = 0,
609 .sh_addralign = 1,
610 .sh_entsize = 0,
611 });634 });
612 self.shstrtab_dirty = true;635 self.shstrtab_dirty = true;
613 self.shdr_table_dirty = true;
614 }636 }
615637
616 if (self.strtab_section_index == null) {638 if (self.strtab_section_index == null) {
617 self.strtab_section_index = @intCast(self.shdrs.items.len);
618 assert(self.strtab.buffer.items.len == 0);639 assert(self.strtab.buffer.items.len == 0);
619 try self.strtab.buffer.append(gpa, 0); // need a 0 at position 0640 try self.strtab.buffer.append(gpa, 0); // need a 0 at position 0
620 const off = self.findFreeSpace(self.strtab.buffer.items.len, 1);641 self.strtab_section_index = try self.allocateNonAllocSection(.{
621 log.debug("found .strtab free space 0x{x} to 0x{x}", .{ off, off + self.strtab.buffer.items.len });642 .name = ".strtab",
622 try self.shdrs.append(gpa, .{643 .size = @intCast(self.strtab.buffer.items.len),
623 .sh_name = try self.shstrtab.insert(gpa, ".strtab"),644 .type = elf.SHT_STRTAB,
624 .sh_type = elf.SHT_STRTAB,
625 .sh_flags = 0,
626 .sh_addr = 0,
627 .sh_offset = off,
628 .sh_size = self.strtab.buffer.items.len,
629 .sh_link = 0,
630 .sh_info = 0,
631 .sh_addralign = 1,
632 .sh_entsize = 0,
633 });645 });
634 self.strtab_dirty = true;646 self.strtab_dirty = true;
635 self.shdr_table_dirty = true;
636 }647 }
637648
638 if (self.text_section_index == null) {649 if (self.text_section_index == null) {
...@@ -682,146 +693,66 @@ pub fn populateMissingMetadata(self: *Elf) !void {...@@ -682,146 +693,66 @@ pub fn populateMissingMetadata(self: *Elf) !void {
682 }693 }
683694
684 if (self.symtab_section_index == null) {695 if (self.symtab_section_index == null) {
685 self.symtab_section_index = @intCast(self.shdrs.items.len);
686 const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym);696 const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym);
687 const each_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym);697 const each_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Sym) else @sizeOf(elf.Elf64_Sym);
688 const file_size = self.base.options.symbol_count_hint * each_size;698 self.symtab_section_index = try self.allocateNonAllocSection(.{
689 const off = self.findFreeSpace(file_size, min_align);699 .name = ".symtab",
690 log.debug("found symtab free space 0x{x} to 0x{x}", .{ off, off + file_size });700 .size = self.base.options.symbol_count_hint * each_size,
691 try self.shdrs.append(gpa, .{701 .alignment = min_align,
692 .sh_name = try self.shstrtab.insert(gpa, ".symtab"),702 .type = elf.SHT_SYMTAB,
693 .sh_type = elf.SHT_SYMTAB,703 .link = self.strtab_section_index.?, // Index of associated string table
694 .sh_flags = 0,704 .info = @intCast(self.symbols.items.len),
695 .sh_addr = 0,705 .entsize = each_size,
696 .sh_offset = off,
697 .sh_size = file_size,
698 // The section header index of the associated string table.
699 .sh_link = self.strtab_section_index.?,
700 .sh_info = @intCast(self.symbols.items.len),
701 .sh_addralign = min_align,
702 .sh_entsize = each_size,
703 });706 });
704 self.shdr_table_dirty = true;707 self.shdr_table_dirty = true;
705 }708 }
706709
707 if (self.dwarf) |*dw| {710 if (self.dwarf) |*dw| {
708 if (self.debug_str_section_index == null) {711 if (self.debug_str_section_index == null) {
709 self.debug_str_section_index = @intCast(self.shdrs.items.len);
710 assert(dw.strtab.buffer.items.len == 0);712 assert(dw.strtab.buffer.items.len == 0);
711 try dw.strtab.buffer.append(gpa, 0);713 try dw.strtab.buffer.append(gpa, 0);
712 try self.shdrs.append(gpa, .{714 self.debug_str_section_index = try self.allocateNonAllocSection(.{
713 .sh_name = try self.shstrtab.insert(gpa, ".debug_str"),715 .name = ".debug_str",
714 .sh_type = elf.SHT_PROGBITS,716 .size = @intCast(dw.strtab.buffer.items.len),
715 .sh_flags = elf.SHF_MERGE | elf.SHF_STRINGS,717 .flags = elf.SHF_MERGE | elf.SHF_STRINGS,
716 .sh_addr = 0,718 .entsize = 1,
717 .sh_offset = 0,
718 .sh_size = 0,
719 .sh_link = 0,
720 .sh_info = 0,
721 .sh_addralign = 1,
722 .sh_entsize = 1,
723 });719 });
724 self.debug_strtab_dirty = true;720 self.debug_strtab_dirty = true;
725 self.shdr_table_dirty = true;
726 }721 }
727722
728 if (self.debug_info_section_index == null) {723 if (self.debug_info_section_index == null) {
729 self.debug_info_section_index = @intCast(self.shdrs.items.len);724 self.debug_info_section_index = try self.allocateNonAllocSection(.{
730 const file_size_hint = 200;725 .name = ".debug_info",
731 const p_align = 1;726 .size = 200,
732 const off = self.findFreeSpace(file_size_hint, p_align);727 .alignment = 1,
733 log.debug("found .debug_info free space 0x{x} to 0x{x}", .{
734 off,
735 off + file_size_hint,
736 });
737 try self.shdrs.append(gpa, .{
738 .sh_name = try self.shstrtab.insert(gpa, ".debug_info"),
739 .sh_type = elf.SHT_PROGBITS,
740 .sh_flags = 0,
741 .sh_addr = 0,
742 .sh_offset = off,
743 .sh_size = file_size_hint,
744 .sh_link = 0,
745 .sh_info = 0,
746 .sh_addralign = p_align,
747 .sh_entsize = 0,
748 });728 });
749 self.shdr_table_dirty = true;
750 self.debug_info_header_dirty = true;729 self.debug_info_header_dirty = true;
751 }730 }
752731
753 if (self.debug_abbrev_section_index == null) {732 if (self.debug_abbrev_section_index == null) {
754 self.debug_abbrev_section_index = @intCast(self.shdrs.items.len);733 self.debug_abbrev_section_index = try self.allocateNonAllocSection(.{
755 const file_size_hint = 128;734 .name = ".debug_abbrev",
756 const p_align = 1;735 .size = 128,
757 const off = self.findFreeSpace(file_size_hint, p_align);736 .alignment = 1,
758 log.debug("found .debug_abbrev free space 0x{x} to 0x{x}", .{
759 off,
760 off + file_size_hint,
761 });737 });
762 try self.shdrs.append(gpa, .{
763 .sh_name = try self.shstrtab.insert(gpa, ".debug_abbrev"),
764 .sh_type = elf.SHT_PROGBITS,
765 .sh_flags = 0,
766 .sh_addr = 0,
767 .sh_offset = off,
768 .sh_size = file_size_hint,
769 .sh_link = 0,
770 .sh_info = 0,
771 .sh_addralign = p_align,
772 .sh_entsize = 0,
773 });
774 self.shdr_table_dirty = true;
775 self.debug_abbrev_section_dirty = true;738 self.debug_abbrev_section_dirty = true;
776 }739 }
777740
778 if (self.debug_aranges_section_index == null) {741 if (self.debug_aranges_section_index == null) {
779 self.debug_aranges_section_index = @intCast(self.shdrs.items.len);742 self.debug_aranges_section_index = try self.allocateNonAllocSection(.{
780 const file_size_hint = 160;743 .name = ".debug_aranges",
781 const p_align = 16;744 .size = 160,
782 const off = self.findFreeSpace(file_size_hint, p_align);745 .alignment = 16,
783 log.debug("found .debug_aranges free space 0x{x} to 0x{x}", .{
784 off,
785 off + file_size_hint,
786 });
787 try self.shdrs.append(gpa, .{
788 .sh_name = try self.shstrtab.insert(gpa, ".debug_aranges"),
789 .sh_type = elf.SHT_PROGBITS,
790 .sh_flags = 0,
791 .sh_addr = 0,
792 .sh_offset = off,
793 .sh_size = file_size_hint,
794 .sh_link = 0,
795 .sh_info = 0,
796 .sh_addralign = p_align,
797 .sh_entsize = 0,
798 });746 });
799 self.shdr_table_dirty = true;
800 self.debug_aranges_section_dirty = true;747 self.debug_aranges_section_dirty = true;
801 }748 }
802749
803 if (self.debug_line_section_index == null) {750 if (self.debug_line_section_index == null) {
804 self.debug_line_section_index = @intCast(self.shdrs.items.len);751 self.debug_line_section_index = try self.allocateNonAllocSection(.{
805 const file_size_hint = 250;752 .name = ".debug_line",
806 const p_align = 1;753 .size = 250,
807 const off = self.findFreeSpace(file_size_hint, p_align);754 .alignment = 1,
808 log.debug("found .debug_line free space 0x{x} to 0x{x}", .{
809 off,
810 off + file_size_hint,
811 });
812 try self.shdrs.append(gpa, .{
813 .sh_name = try self.shstrtab.insert(gpa, ".debug_line"),
814 .sh_type = elf.SHT_PROGBITS,
815 .sh_flags = 0,
816 .sh_addr = 0,
817 .sh_offset = off,
818 .sh_size = file_size_hint,
819 .sh_link = 0,
820 .sh_info = 0,
821 .sh_addralign = p_align,
822 .sh_entsize = 0,
823 });755 });
824 self.shdr_table_dirty = true;
825 self.debug_line_header_dirty = true;756 self.debug_line_header_dirty = true;
826 }757 }
827 }758 }