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
458458 try self.shdrs.ensureUnusedCapacity(gpa, 1);
459459 const sh_name = try self.shstrtab.insert(gpa, opts.name);
460460 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})", .{
462462 opts.name,
463463 opts.phdr_index,
464464 phdr.p_offset,
......@@ -482,6 +482,39 @@ fn allocateAllocSection(self: *Elf, opts: AllocateAllocSectionOpts) error{OutOfM
482482 return index;
483483}
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
485518pub fn populateMissingMetadata(self: *Elf) !void {
486519 const gpa = self.base.allocator;
487520 const small_ptr = switch (self.ptr_width) {
......@@ -592,47 +625,25 @@ pub fn populateMissingMetadata(self: *Elf) !void {
592625 }
593626
594627 if (self.shstrtab_section_index == null) {
595 self.shstrtab_section_index = @intCast(self.shdrs.items.len);
596628 assert(self.shstrtab.buffer.items.len == 0);
597629 try self.shstrtab.buffer.append(gpa, 0); // need a 0 at position 0
598 const off = self.findFreeSpace(self.shstrtab.buffer.items.len, 1);
599 log.debug("found .shstrtab free space 0x{x} to 0x{x}", .{ off, off + self.shstrtab.buffer.items.len });
600 try self.shdrs.append(gpa, .{
601 .sh_name = try self.shstrtab.insert(gpa, ".shstrtab"),
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,
630 self.shstrtab_section_index = try self.allocateNonAllocSection(.{
631 .name = ".shstrtab",
632 .size = @intCast(self.shstrtab.buffer.items.len),
633 .type = elf.SHT_STRTAB,
611634 });
612635 self.shstrtab_dirty = true;
613 self.shdr_table_dirty = true;
614636 }
615637
616638 if (self.strtab_section_index == null) {
617 self.strtab_section_index = @intCast(self.shdrs.items.len);
618639 assert(self.strtab.buffer.items.len == 0);
619640 try self.strtab.buffer.append(gpa, 0); // need a 0 at position 0
620 const off = self.findFreeSpace(self.strtab.buffer.items.len, 1);
621 log.debug("found .strtab free space 0x{x} to 0x{x}", .{ off, off + self.strtab.buffer.items.len });
622 try self.shdrs.append(gpa, .{
623 .sh_name = try self.shstrtab.insert(gpa, ".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,
641 self.strtab_section_index = try self.allocateNonAllocSection(.{
642 .name = ".strtab",
643 .size = @intCast(self.strtab.buffer.items.len),
644 .type = elf.SHT_STRTAB,
633645 });
634646 self.strtab_dirty = true;
635 self.shdr_table_dirty = true;
636647 }
637648
638649 if (self.text_section_index == null) {
......@@ -682,146 +693,66 @@ pub fn populateMissingMetadata(self: *Elf) !void {
682693 }
683694
684695 if (self.symtab_section_index == null) {
685 self.symtab_section_index = @intCast(self.shdrs.items.len);
686696 const min_align: u16 = if (small_ptr) @alignOf(elf.Elf32_Sym) else @alignOf(elf.Elf64_Sym);
687697 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;
689 const off = self.findFreeSpace(file_size, min_align);
690 log.debug("found symtab free space 0x{x} to 0x{x}", .{ off, off + file_size });
691 try self.shdrs.append(gpa, .{
692 .sh_name = try self.shstrtab.insert(gpa, ".symtab"),
693 .sh_type = elf.SHT_SYMTAB,
694 .sh_flags = 0,
695 .sh_addr = 0,
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,
698 self.symtab_section_index = try self.allocateNonAllocSection(.{
699 .name = ".symtab",
700 .size = self.base.options.symbol_count_hint * each_size,
701 .alignment = min_align,
702 .type = elf.SHT_SYMTAB,
703 .link = self.strtab_section_index.?, // Index of associated string table
704 .info = @intCast(self.symbols.items.len),
705 .entsize = each_size,
703706 });
704707 self.shdr_table_dirty = true;
705708 }
706709
707710 if (self.dwarf) |*dw| {
708711 if (self.debug_str_section_index == null) {
709 self.debug_str_section_index = @intCast(self.shdrs.items.len);
710712 assert(dw.strtab.buffer.items.len == 0);
711713 try dw.strtab.buffer.append(gpa, 0);
712 try self.shdrs.append(gpa, .{
713 .sh_name = try self.shstrtab.insert(gpa, ".debug_str"),
714 .sh_type = elf.SHT_PROGBITS,
715 .sh_flags = elf.SHF_MERGE | elf.SHF_STRINGS,
716 .sh_addr = 0,
717 .sh_offset = 0,
718 .sh_size = 0,
719 .sh_link = 0,
720 .sh_info = 0,
721 .sh_addralign = 1,
722 .sh_entsize = 1,
714 self.debug_str_section_index = try self.allocateNonAllocSection(.{
715 .name = ".debug_str",
716 .size = @intCast(dw.strtab.buffer.items.len),
717 .flags = elf.SHF_MERGE | elf.SHF_STRINGS,
718 .entsize = 1,
723719 });
724720 self.debug_strtab_dirty = true;
725 self.shdr_table_dirty = true;
726721 }
727722
728723 if (self.debug_info_section_index == null) {
729 self.debug_info_section_index = @intCast(self.shdrs.items.len);
730 const file_size_hint = 200;
731 const p_align = 1;
732 const off = self.findFreeSpace(file_size_hint, p_align);
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,
724 self.debug_info_section_index = try self.allocateNonAllocSection(.{
725 .name = ".debug_info",
726 .size = 200,
727 .alignment = 1,
748728 });
749 self.shdr_table_dirty = true;
750729 self.debug_info_header_dirty = true;
751730 }
752731
753732 if (self.debug_abbrev_section_index == null) {
754 self.debug_abbrev_section_index = @intCast(self.shdrs.items.len);
755 const file_size_hint = 128;
756 const p_align = 1;
757 const off = self.findFreeSpace(file_size_hint, p_align);
758 log.debug("found .debug_abbrev free space 0x{x} to 0x{x}", .{
759 off,
760 off + file_size_hint,
733 self.debug_abbrev_section_index = try self.allocateNonAllocSection(.{
734 .name = ".debug_abbrev",
735 .size = 128,
736 .alignment = 1,
761737 });
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;
775738 self.debug_abbrev_section_dirty = true;
776739 }
777740
778741 if (self.debug_aranges_section_index == null) {
779 self.debug_aranges_section_index = @intCast(self.shdrs.items.len);
780 const file_size_hint = 160;
781 const p_align = 16;
782 const off = self.findFreeSpace(file_size_hint, p_align);
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,
742 self.debug_aranges_section_index = try self.allocateNonAllocSection(.{
743 .name = ".debug_aranges",
744 .size = 160,
745 .alignment = 16,
798746 });
799 self.shdr_table_dirty = true;
800747 self.debug_aranges_section_dirty = true;
801748 }
802749
803750 if (self.debug_line_section_index == null) {
804 self.debug_line_section_index = @intCast(self.shdrs.items.len);
805 const file_size_hint = 250;
806 const p_align = 1;
807 const off = self.findFreeSpace(file_size_hint, p_align);
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,
751 self.debug_line_section_index = try self.allocateNonAllocSection(.{
752 .name = ".debug_line",
753 .size = 250,
754 .alignment = 1,
823755 });
824 self.shdr_table_dirty = true;
825756 self.debug_line_header_dirty = true;
826757 }
827758 }