| ... | @@ -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 | } |
| 484 | | 484 | |
| | 485 | const 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 | |
| | 496 | fn 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 | |
| 485 | pub fn populateMissingMetadata(self: *Elf) !void { | 518 | pub 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 | } |
| 593 | | 626 | |
| 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 0 | 629 | 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 | } |
| 615 | | 637 | |
| 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 0 | 640 | 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 | } |
| 637 | | 648 | |
| 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 | } |
| 683 | | 694 | |
| 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 | } |
| 706 | | 709 | |
| 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 | } |
| 727 | | 722 | |
| 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 | } |
| 752 | | 731 | |
| 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 | } |
| 777 | | 740 | |
| 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 | } |
| 802 | | 749 | |
| 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 | } |