| author | |
| committer | |
| log | a6bf762a8ba3672c40e369f832d38f864d86fbd9 |
| tree | 30331379e4c1e3e805a127d7de0cc9ff4e274df2 |
| parent | 7d54c62c8a55240bbe144ab03c78573a344598ce |
2 files changed, 321 insertions(+), 322 deletions(-)
src/link/Elf.zig+3-313| ... | @@ -387,8 +387,7 @@ pub fn createEmpty( | ... | @@ -387,8 +387,7 @@ pub fn createEmpty( |
| 387 | )}), | 387 | )}), |
| 388 | } }); | 388 | } }); |
| 389 | self.zig_object_index = index; | 389 | self.zig_object_index = index; |
| 390 | try self.zigObjectPtr().?.init(self); | 390 | try self.zigObjectPtr().?.init(self, .{ |
| 391 | try self.initMetadata(.{ | ||
| 392 | .symbol_count_hint = options.symbol_count_hint, | 391 | .symbol_count_hint = options.symbol_count_hint, |
| 393 | .program_code_size_hint = options.program_code_size_hint, | 392 | .program_code_size_hint = options.program_code_size_hint, |
| 394 | }); | 393 | }); |
| ... | @@ -574,315 +573,6 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 { | ... | @@ -574,315 +573,6 @@ pub fn findFreeSpace(self: *Elf, object_size: u64, min_alignment: u64) !u64 { |
| 574 | return start; | 573 | return start; |
| 575 | } | 574 | } |
| 576 | 575 | ||
| 577 | pub const InitMetadataOptions = struct { | ||
| 578 | symbol_count_hint: u64, | ||
| 579 | program_code_size_hint: u64, | ||
| 580 | }; | ||
| 581 | |||
| 582 | /// TODO move to ZigObject | ||
| 583 | pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ||
| 584 | const gpa = self.base.comp.gpa; | ||
| 585 | const ptr_size = self.ptrWidthBytes(); | ||
| 586 | const target = self.base.comp.root_mod.resolved_target.result; | ||
| 587 | const ptr_bit_width = target.ptrBitWidth(); | ||
| 588 | const zo = self.zigObjectPtr().?; | ||
| 589 | |||
| 590 | const fillSection = struct { | ||
| 591 | fn fillSection(elf_file: *Elf, shdr: *elf.Elf64_Shdr, size: u64, phndx: ?u16) !void { | ||
| 592 | if (elf_file.base.isRelocatable()) { | ||
| 593 | const off = try elf_file.findFreeSpace(size, shdr.sh_addralign); | ||
| 594 | shdr.sh_offset = off; | ||
| 595 | shdr.sh_size = size; | ||
| 596 | } else { | ||
| 597 | const phdr = elf_file.phdrs.items[phndx.?]; | ||
| 598 | shdr.sh_addr = phdr.p_vaddr; | ||
| 599 | shdr.sh_offset = phdr.p_offset; | ||
| 600 | shdr.sh_size = phdr.p_memsz; | ||
| 601 | } | ||
| 602 | } | ||
| 603 | }.fillSection; | ||
| 604 | |||
| 605 | comptime assert(number_of_zig_segments == 5); | ||
| 606 | |||
| 607 | if (!self.base.isRelocatable()) { | ||
| 608 | if (self.phdr_zig_load_re_index == null) { | ||
| 609 | const filesz = options.program_code_size_hint; | ||
| 610 | const off = try self.findFreeSpace(filesz, self.page_size); | ||
| 611 | self.phdr_zig_load_re_index = try self.addPhdr(.{ | ||
| 612 | .type = elf.PT_LOAD, | ||
| 613 | .offset = off, | ||
| 614 | .filesz = filesz, | ||
| 615 | .addr = if (ptr_bit_width >= 32) 0x4000000 else 0x4000, | ||
| 616 | .memsz = filesz, | ||
| 617 | .@"align" = self.page_size, | ||
| 618 | .flags = elf.PF_X | elf.PF_R | elf.PF_W, | ||
| 619 | }); | ||
| 620 | } | ||
| 621 | |||
| 622 | if (self.phdr_zig_load_ro_index == null) { | ||
| 623 | const alignment = self.page_size; | ||
| 624 | const filesz: u64 = 1024; | ||
| 625 | const off = try self.findFreeSpace(filesz, alignment); | ||
| 626 | self.phdr_zig_load_ro_index = try self.addPhdr(.{ | ||
| 627 | .type = elf.PT_LOAD, | ||
| 628 | .offset = off, | ||
| 629 | .filesz = filesz, | ||
| 630 | .addr = if (ptr_bit_width >= 32) 0xc000000 else 0xa000, | ||
| 631 | .memsz = filesz, | ||
| 632 | .@"align" = alignment, | ||
| 633 | .flags = elf.PF_R | elf.PF_W, | ||
| 634 | }); | ||
| 635 | } | ||
| 636 | |||
| 637 | if (self.phdr_zig_load_rw_index == null) { | ||
| 638 | const alignment = self.page_size; | ||
| 639 | const filesz: u64 = 1024; | ||
| 640 | const off = try self.findFreeSpace(filesz, alignment); | ||
| 641 | self.phdr_zig_load_rw_index = try self.addPhdr(.{ | ||
| 642 | .type = elf.PT_LOAD, | ||
| 643 | .offset = off, | ||
| 644 | .filesz = filesz, | ||
| 645 | .addr = if (ptr_bit_width >= 32) 0x10000000 else 0xc000, | ||
| 646 | .memsz = filesz, | ||
| 647 | .@"align" = alignment, | ||
| 648 | .flags = elf.PF_R | elf.PF_W, | ||
| 649 | }); | ||
| 650 | } | ||
| 651 | |||
| 652 | if (self.phdr_zig_load_zerofill_index == null) { | ||
| 653 | const alignment = self.page_size; | ||
| 654 | self.phdr_zig_load_zerofill_index = try self.addPhdr(.{ | ||
| 655 | .type = elf.PT_LOAD, | ||
| 656 | .addr = if (ptr_bit_width >= 32) 0x14000000 else 0xf000, | ||
| 657 | .memsz = 1024, | ||
| 658 | .@"align" = alignment, | ||
| 659 | .flags = elf.PF_R | elf.PF_W, | ||
| 660 | }); | ||
| 661 | } | ||
| 662 | } | ||
| 663 | |||
| 664 | if (self.zig_text_section_index == null) { | ||
| 665 | self.zig_text_section_index = try self.addSection(.{ | ||
| 666 | .name = try self.insertShString(".text.zig"), | ||
| 667 | .type = elf.SHT_PROGBITS, | ||
| 668 | .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR, | ||
| 669 | .addralign = 1, | ||
| 670 | .offset = std.math.maxInt(u64), | ||
| 671 | }); | ||
| 672 | const shdr = &self.shdrs.items[self.zig_text_section_index.?]; | ||
| 673 | try fillSection(self, shdr, options.program_code_size_hint, self.phdr_zig_load_re_index); | ||
| 674 | if (self.base.isRelocatable()) { | ||
| 675 | const rela_shndx = try self.addRelaShdr(try self.insertShString(".rela.text.zig"), self.zig_text_section_index.?); | ||
| 676 | try self.output_rela_sections.putNoClobber(gpa, self.zig_text_section_index.?, .{ | ||
| 677 | .shndx = rela_shndx, | ||
| 678 | }); | ||
| 679 | } else { | ||
| 680 | try self.phdr_to_shdr_table.putNoClobber( | ||
| 681 | gpa, | ||
| 682 | self.zig_text_section_index.?, | ||
| 683 | self.phdr_zig_load_re_index.?, | ||
| 684 | ); | ||
| 685 | } | ||
| 686 | try self.output_sections.putNoClobber(gpa, self.zig_text_section_index.?, .{}); | ||
| 687 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{}); | ||
| 688 | } | ||
| 689 | |||
| 690 | if (self.zig_data_rel_ro_section_index == null) { | ||
| 691 | self.zig_data_rel_ro_section_index = try self.addSection(.{ | ||
| 692 | .name = try self.insertShString(".data.rel.ro.zig"), | ||
| 693 | .type = elf.SHT_PROGBITS, | ||
| 694 | .addralign = 1, | ||
| 695 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | ||
| 696 | .offset = std.math.maxInt(u64), | ||
| 697 | }); | ||
| 698 | const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?]; | ||
| 699 | try fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index); | ||
| 700 | if (self.base.isRelocatable()) { | ||
| 701 | const rela_shndx = try self.addRelaShdr( | ||
| 702 | try self.insertShString(".rela.data.rel.ro.zig"), | ||
| 703 | self.zig_data_rel_ro_section_index.?, | ||
| 704 | ); | ||
| 705 | try self.output_rela_sections.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, .{ | ||
| 706 | .shndx = rela_shndx, | ||
| 707 | }); | ||
| 708 | } else { | ||
| 709 | try self.phdr_to_shdr_table.putNoClobber( | ||
| 710 | gpa, | ||
| 711 | self.zig_data_rel_ro_section_index.?, | ||
| 712 | self.phdr_zig_load_ro_index.?, | ||
| 713 | ); | ||
| 714 | } | ||
| 715 | try self.output_sections.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, .{}); | ||
| 716 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_rel_ro_section_index.?, .{}); | ||
| 717 | } | ||
| 718 | |||
| 719 | if (self.zig_data_section_index == null) { | ||
| 720 | self.zig_data_section_index = try self.addSection(.{ | ||
| 721 | .name = try self.insertShString(".data.zig"), | ||
| 722 | .type = elf.SHT_PROGBITS, | ||
| 723 | .addralign = ptr_size, | ||
| 724 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | ||
| 725 | .offset = std.math.maxInt(u64), | ||
| 726 | }); | ||
| 727 | const shdr = &self.shdrs.items[self.zig_data_section_index.?]; | ||
| 728 | try fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index); | ||
| 729 | if (self.base.isRelocatable()) { | ||
| 730 | const rela_shndx = try self.addRelaShdr( | ||
| 731 | try self.insertShString(".rela.data.zig"), | ||
| 732 | self.zig_data_section_index.?, | ||
| 733 | ); | ||
| 734 | try self.output_rela_sections.putNoClobber(gpa, self.zig_data_section_index.?, .{ | ||
| 735 | .shndx = rela_shndx, | ||
| 736 | }); | ||
| 737 | } else { | ||
| 738 | try self.phdr_to_shdr_table.putNoClobber( | ||
| 739 | gpa, | ||
| 740 | self.zig_data_section_index.?, | ||
| 741 | self.phdr_zig_load_rw_index.?, | ||
| 742 | ); | ||
| 743 | } | ||
| 744 | try self.output_sections.putNoClobber(gpa, self.zig_data_section_index.?, .{}); | ||
| 745 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_data_section_index.?, .{}); | ||
| 746 | } | ||
| 747 | |||
| 748 | if (self.zig_bss_section_index == null) { | ||
| 749 | self.zig_bss_section_index = try self.addSection(.{ | ||
| 750 | .name = try self.insertShString(".bss.zig"), | ||
| 751 | .type = elf.SHT_NOBITS, | ||
| 752 | .addralign = ptr_size, | ||
| 753 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | ||
| 754 | .offset = 0, | ||
| 755 | }); | ||
| 756 | const shdr = &self.shdrs.items[self.zig_bss_section_index.?]; | ||
| 757 | if (self.phdr_zig_load_zerofill_index) |phndx| { | ||
| 758 | const phdr = self.phdrs.items[phndx]; | ||
| 759 | shdr.sh_addr = phdr.p_vaddr; | ||
| 760 | shdr.sh_size = phdr.p_memsz; | ||
| 761 | try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_bss_section_index.?, phndx); | ||
| 762 | } else { | ||
| 763 | shdr.sh_size = 1024; | ||
| 764 | } | ||
| 765 | try self.output_sections.putNoClobber(gpa, self.zig_bss_section_index.?, .{}); | ||
| 766 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{}); | ||
| 767 | } | ||
| 768 | |||
| 769 | if (zo.dwarf) |*dwarf| { | ||
| 770 | const addSectionSymbol = struct { | ||
| 771 | fn addSectionSymbol( | ||
| 772 | zig_object: *ZigObject, | ||
| 773 | alloc: Allocator, | ||
| 774 | name: [:0]const u8, | ||
| 775 | alignment: Atom.Alignment, | ||
| 776 | shndx: u32, | ||
| 777 | ) !Symbol.Index { | ||
| 778 | const name_off = try zig_object.addString(alloc, name); | ||
| 779 | const index = try zig_object.newSymbolWithAtom(alloc, name_off); | ||
| 780 | const sym = zig_object.symbol(index); | ||
| 781 | const esym = &zig_object.symtab.items(.elf_sym)[sym.esym_index]; | ||
| 782 | esym.st_info |= elf.STT_SECTION; | ||
| 783 | const atom_ptr = zig_object.atom(sym.ref.index).?; | ||
| 784 | atom_ptr.alignment = alignment; | ||
| 785 | atom_ptr.output_section_index = shndx; | ||
| 786 | return index; | ||
| 787 | } | ||
| 788 | }.addSectionSymbol; | ||
| 789 | |||
| 790 | if (self.debug_str_section_index == null) { | ||
| 791 | self.debug_str_section_index = try self.addSection(.{ | ||
| 792 | .name = try self.insertShString(".debug_str"), | ||
| 793 | .flags = elf.SHF_MERGE | elf.SHF_STRINGS, | ||
| 794 | .entsize = 1, | ||
| 795 | .type = elf.SHT_PROGBITS, | ||
| 796 | .addralign = 1, | ||
| 797 | }); | ||
| 798 | zo.debug_str_section_dirty = true; | ||
| 799 | zo.debug_str_index = try addSectionSymbol(zo, gpa, ".debug_str", .@"1", self.debug_str_section_index.?); | ||
| 800 | try self.output_sections.putNoClobber(gpa, self.debug_str_section_index.?, .{}); | ||
| 801 | } | ||
| 802 | |||
| 803 | if (self.debug_info_section_index == null) { | ||
| 804 | self.debug_info_section_index = try self.addSection(.{ | ||
| 805 | .name = try self.insertShString(".debug_info"), | ||
| 806 | .type = elf.SHT_PROGBITS, | ||
| 807 | .addralign = 1, | ||
| 808 | }); | ||
| 809 | zo.debug_info_section_dirty = true; | ||
| 810 | zo.debug_info_index = try addSectionSymbol(zo, gpa, ".debug_info", .@"1", self.debug_info_section_index.?); | ||
| 811 | try self.output_sections.putNoClobber(gpa, self.debug_info_section_index.?, .{}); | ||
| 812 | } | ||
| 813 | |||
| 814 | if (self.debug_abbrev_section_index == null) { | ||
| 815 | self.debug_abbrev_section_index = try self.addSection(.{ | ||
| 816 | .name = try self.insertShString(".debug_abbrev"), | ||
| 817 | .type = elf.SHT_PROGBITS, | ||
| 818 | .addralign = 1, | ||
| 819 | }); | ||
| 820 | zo.debug_abbrev_section_dirty = true; | ||
| 821 | zo.debug_abbrev_index = try addSectionSymbol(zo, gpa, ".debug_abbrev", .@"1", self.debug_abbrev_section_index.?); | ||
| 822 | try self.output_sections.putNoClobber(gpa, self.debug_abbrev_section_index.?, .{}); | ||
| 823 | } | ||
| 824 | |||
| 825 | if (self.debug_aranges_section_index == null) { | ||
| 826 | self.debug_aranges_section_index = try self.addSection(.{ | ||
| 827 | .name = try self.insertShString(".debug_aranges"), | ||
| 828 | .type = elf.SHT_PROGBITS, | ||
| 829 | .addralign = 16, | ||
| 830 | }); | ||
| 831 | zo.debug_aranges_section_dirty = true; | ||
| 832 | zo.debug_aranges_index = try addSectionSymbol(zo, gpa, ".debug_aranges", .@"16", self.debug_aranges_section_index.?); | ||
| 833 | try self.output_sections.putNoClobber(gpa, self.debug_aranges_section_index.?, .{}); | ||
| 834 | } | ||
| 835 | |||
| 836 | if (self.debug_line_section_index == null) { | ||
| 837 | self.debug_line_section_index = try self.addSection(.{ | ||
| 838 | .name = try self.insertShString(".debug_line"), | ||
| 839 | .type = elf.SHT_PROGBITS, | ||
| 840 | .addralign = 1, | ||
| 841 | }); | ||
| 842 | zo.debug_line_section_dirty = true; | ||
| 843 | zo.debug_line_index = try addSectionSymbol(zo, gpa, ".debug_line", .@"1", self.debug_line_section_index.?); | ||
| 844 | try self.output_sections.putNoClobber(gpa, self.debug_line_section_index.?, .{}); | ||
| 845 | } | ||
| 846 | |||
| 847 | if (self.debug_line_str_section_index == null) { | ||
| 848 | self.debug_line_str_section_index = try self.addSection(.{ | ||
| 849 | .name = try self.insertShString(".debug_line_str"), | ||
| 850 | .flags = elf.SHF_MERGE | elf.SHF_STRINGS, | ||
| 851 | .entsize = 1, | ||
| 852 | .type = elf.SHT_PROGBITS, | ||
| 853 | .addralign = 1, | ||
| 854 | }); | ||
| 855 | zo.debug_line_str_section_dirty = true; | ||
| 856 | zo.debug_line_str_index = try addSectionSymbol(zo, gpa, ".debug_line_str", .@"1", self.debug_line_str_section_index.?); | ||
| 857 | try self.output_sections.putNoClobber(gpa, self.debug_line_str_section_index.?, .{}); | ||
| 858 | } | ||
| 859 | |||
| 860 | if (self.debug_loclists_section_index == null) { | ||
| 861 | self.debug_loclists_section_index = try self.addSection(.{ | ||
| 862 | .name = try self.insertShString(".debug_loclists"), | ||
| 863 | .type = elf.SHT_PROGBITS, | ||
| 864 | .addralign = 1, | ||
| 865 | }); | ||
| 866 | zo.debug_loclists_section_dirty = true; | ||
| 867 | zo.debug_loclists_index = try addSectionSymbol(zo, gpa, ".debug_loclists", .@"1", self.debug_loclists_section_index.?); | ||
| 868 | try self.output_sections.putNoClobber(gpa, self.debug_loclists_section_index.?, .{}); | ||
| 869 | } | ||
| 870 | |||
| 871 | if (self.debug_rnglists_section_index == null) { | ||
| 872 | self.debug_rnglists_section_index = try self.addSection(.{ | ||
| 873 | .name = try self.insertShString(".debug_rnglists"), | ||
| 874 | .type = elf.SHT_PROGBITS, | ||
| 875 | .addralign = 1, | ||
| 876 | }); | ||
| 877 | zo.debug_rnglists_section_dirty = true; | ||
| 878 | zo.debug_rnglists_index = try addSectionSymbol(zo, gpa, ".debug_rnglists", .@"1", self.debug_rnglists_section_index.?); | ||
| 879 | try self.output_sections.putNoClobber(gpa, self.debug_rnglists_section_index.?, .{}); | ||
| 880 | } | ||
| 881 | |||
| 882 | try dwarf.initMetadata(); | ||
| 883 | } | ||
| 884 | } | ||
| 885 | |||
| 886 | pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { | 576 | pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { |
| 887 | const shdr = &self.shdrs.items[shdr_index]; | 577 | const shdr = &self.shdrs.items[shdr_index]; |
| 888 | const maybe_phdr = if (self.phdr_to_shdr_table.get(shdr_index)) |phndx| &self.phdrs.items[phndx] else null; | 578 | const maybe_phdr = if (self.phdr_to_shdr_table.get(shdr_index)) |phndx| &self.phdrs.items[phndx] else null; |
| ... | @@ -5069,7 +4759,7 @@ pub fn isDebugSection(self: Elf, shndx: u32) bool { | ... | @@ -5069,7 +4759,7 @@ pub fn isDebugSection(self: Elf, shndx: u32) bool { |
| 5069 | return false; | 4759 | return false; |
| 5070 | } | 4760 | } |
| 5071 | 4761 | ||
| 5072 | fn addPhdr(self: *Elf, opts: struct { | 4762 | pub fn addPhdr(self: *Elf, opts: struct { |
| 5073 | type: u32 = 0, | 4763 | type: u32 = 0, |
| 5074 | flags: u32 = 0, | 4764 | flags: u32 = 0, |
| 5075 | @"align": u64 = 0, | 4765 | @"align": u64 = 0, |
| ... | @@ -5746,7 +5436,7 @@ fn requiresThunks(self: Elf) bool { | ... | @@ -5746,7 +5436,7 @@ fn requiresThunks(self: Elf) bool { |
| 5746 | /// so that we reserve enough space for the program header table up-front. | 5436 | /// so that we reserve enough space for the program header table up-front. |
| 5747 | /// Bump these numbers when adding or deleting a Zig specific pre-allocated segment, or adding | 5437 | /// Bump these numbers when adding or deleting a Zig specific pre-allocated segment, or adding |
| 5748 | /// more special-purpose program headers. | 5438 | /// more special-purpose program headers. |
| 5749 | const number_of_zig_segments = 5; | 5439 | pub const number_of_zig_segments = 4; |
| 5750 | const max_number_of_object_segments = 9; | 5440 | const max_number_of_object_segments = 9; |
| 5751 | const max_number_of_special_phdrs = 5; | 5441 | const max_number_of_special_phdrs = 5; |
| 5752 | 5442 |
src/link/Elf/ZigObject.zig+318-9| ... | @@ -63,24 +63,333 @@ pub const global_symbol_bit: u32 = 0x80000000; | ... | @@ -63,24 +63,333 @@ pub const global_symbol_bit: u32 = 0x80000000; |
| 63 | pub const symbol_mask: u32 = 0x7fffffff; | 63 | pub const symbol_mask: u32 = 0x7fffffff; |
| 64 | pub const SHN_ATOM: u16 = 0x100; | 64 | pub const SHN_ATOM: u16 = 0x100; |
| 65 | 65 | ||
| 66 | pub fn init(self: *ZigObject, elf_file: *Elf) !void { | 66 | const InitOptions = struct { |
| 67 | symbol_count_hint: u64, | ||
| 68 | program_code_size_hint: u64, | ||
| 69 | }; | ||
| 70 | |||
| 71 | pub fn init(self: *ZigObject, elf_file: *Elf, options: InitOptions) !void { | ||
| 67 | const comp = elf_file.base.comp; | 72 | const comp = elf_file.base.comp; |
| 68 | const gpa = comp.gpa; | 73 | const gpa = comp.gpa; |
| 74 | const ptr_size = elf_file.ptrWidthBytes(); | ||
| 75 | const target = elf_file.getTarget(); | ||
| 76 | const ptr_bit_width = target.ptrBitWidth(); | ||
| 69 | 77 | ||
| 70 | try self.atoms.append(gpa, .{ .extra_index = try self.addAtomExtra(gpa, .{}) }); // null input section | 78 | try self.atoms.append(gpa, .{ .extra_index = try self.addAtomExtra(gpa, .{}) }); // null input section |
| 71 | try self.relocs.append(gpa, .{}); // null relocs section | 79 | try self.relocs.append(gpa, .{}); // null relocs section |
| 72 | try self.strtab.buffer.append(gpa, 0); | 80 | try self.strtab.buffer.append(gpa, 0); |
| 73 | 81 | ||
| 74 | const name_off = try self.strtab.insert(gpa, self.path); | 82 | { |
| 75 | const symbol_index = try self.newLocalSymbol(gpa, name_off); | 83 | const name_off = try self.strtab.insert(gpa, self.path); |
| 76 | const sym = self.symbol(symbol_index); | 84 | const symbol_index = try self.newLocalSymbol(gpa, name_off); |
| 77 | const esym = &self.symtab.items(.elf_sym)[sym.esym_index]; | 85 | const sym = self.symbol(symbol_index); |
| 78 | esym.st_info = elf.STT_FILE; | 86 | const esym = &self.symtab.items(.elf_sym)[sym.esym_index]; |
| 79 | esym.st_shndx = elf.SHN_ABS; | 87 | esym.st_info = elf.STT_FILE; |
| 88 | esym.st_shndx = elf.SHN_ABS; | ||
| 89 | } | ||
| 90 | |||
| 91 | const fillSection = struct { | ||
| 92 | fn fillSection(ef: *Elf, shdr: *elf.Elf64_Shdr, size: u64, phndx: ?u16) !void { | ||
| 93 | if (ef.base.isRelocatable()) { | ||
| 94 | const off = try ef.findFreeSpace(size, shdr.sh_addralign); | ||
| 95 | shdr.sh_offset = off; | ||
| 96 | shdr.sh_size = size; | ||
| 97 | } else { | ||
| 98 | const phdr = ef.phdrs.items[phndx.?]; | ||
| 99 | shdr.sh_addr = phdr.p_vaddr; | ||
| 100 | shdr.sh_offset = phdr.p_offset; | ||
| 101 | shdr.sh_size = phdr.p_memsz; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | }.fillSection; | ||
| 105 | |||
| 106 | comptime assert(Elf.number_of_zig_segments == 4); | ||
| 107 | |||
| 108 | if (!elf_file.base.isRelocatable()) { | ||
| 109 | if (elf_file.phdr_zig_load_re_index == null) { | ||
| 110 | const filesz = options.program_code_size_hint; | ||
| 111 | const off = try elf_file.findFreeSpace(filesz, elf_file.page_size); | ||
| 112 | elf_file.phdr_zig_load_re_index = try elf_file.addPhdr(.{ | ||
| 113 | .type = elf.PT_LOAD, | ||
| 114 | .offset = off, | ||
| 115 | .filesz = filesz, | ||
| 116 | .addr = if (ptr_bit_width >= 32) 0x4000000 else 0x4000, | ||
| 117 | .memsz = filesz, | ||
| 118 | .@"align" = elf_file.page_size, | ||
| 119 | .flags = elf.PF_X | elf.PF_R | elf.PF_W, | ||
| 120 | }); | ||
| 121 | } | ||
| 122 | |||
| 123 | if (elf_file.phdr_zig_load_ro_index == null) { | ||
| 124 | const alignment = elf_file.page_size; | ||
| 125 | const filesz: u64 = 1024; | ||
| 126 | const off = try elf_file.findFreeSpace(filesz, alignment); | ||
| 127 | elf_file.phdr_zig_load_ro_index = try elf_file.addPhdr(.{ | ||
| 128 | .type = elf.PT_LOAD, | ||
| 129 | .offset = off, | ||
| 130 | .filesz = filesz, | ||
| 131 | .addr = if (ptr_bit_width >= 32) 0xc000000 else 0xa000, | ||
| 132 | .memsz = filesz, | ||
| 133 | .@"align" = alignment, | ||
| 134 | .flags = elf.PF_R | elf.PF_W, | ||
| 135 | }); | ||
| 136 | } | ||
| 137 | |||
| 138 | if (elf_file.phdr_zig_load_rw_index == null) { | ||
| 139 | const alignment = elf_file.page_size; | ||
| 140 | const filesz: u64 = 1024; | ||
| 141 | const off = try elf_file.findFreeSpace(filesz, alignment); | ||
| 142 | elf_file.phdr_zig_load_rw_index = try elf_file.addPhdr(.{ | ||
| 143 | .type = elf.PT_LOAD, | ||
| 144 | .offset = off, | ||
| 145 | .filesz = filesz, | ||
| 146 | .addr = if (ptr_bit_width >= 32) 0x10000000 else 0xc000, | ||
| 147 | .memsz = filesz, | ||
| 148 | .@"align" = alignment, | ||
| 149 | .flags = elf.PF_R | elf.PF_W, | ||
| 150 | }); | ||
| 151 | } | ||
| 152 | |||
| 153 | if (elf_file.phdr_zig_load_zerofill_index == null) { | ||
| 154 | const alignment = elf_file.page_size; | ||
| 155 | elf_file.phdr_zig_load_zerofill_index = try elf_file.addPhdr(.{ | ||
| 156 | .type = elf.PT_LOAD, | ||
| 157 | .addr = if (ptr_bit_width >= 32) 0x14000000 else 0xf000, | ||
| 158 | .memsz = 1024, | ||
| 159 | .@"align" = alignment, | ||
| 160 | .flags = elf.PF_R | elf.PF_W, | ||
| 161 | }); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 165 | if (elf_file.zig_text_section_index == null) { | ||
| 166 | elf_file.zig_text_section_index = try elf_file.addSection(.{ | ||
| 167 | .name = try elf_file.insertShString(".text.zig"), | ||
| 168 | .type = elf.SHT_PROGBITS, | ||
| 169 | .flags = elf.SHF_ALLOC | elf.SHF_EXECINSTR, | ||
| 170 | .addralign = 1, | ||
| 171 | .offset = std.math.maxInt(u64), | ||
| 172 | }); | ||
| 173 | const shdr = &elf_file.shdrs.items[elf_file.zig_text_section_index.?]; | ||
| 174 | try fillSection(elf_file, shdr, options.program_code_size_hint, elf_file.phdr_zig_load_re_index); | ||
| 175 | if (elf_file.base.isRelocatable()) { | ||
| 176 | const rela_shndx = try elf_file.addRelaShdr( | ||
| 177 | try elf_file.insertShString(".rela.text.zig"), | ||
| 178 | elf_file.zig_text_section_index.?, | ||
| 179 | ); | ||
| 180 | try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{ | ||
| 181 | .shndx = rela_shndx, | ||
| 182 | }); | ||
| 183 | } else { | ||
| 184 | try elf_file.phdr_to_shdr_table.putNoClobber( | ||
| 185 | gpa, | ||
| 186 | elf_file.zig_text_section_index.?, | ||
| 187 | elf_file.phdr_zig_load_re_index.?, | ||
| 188 | ); | ||
| 189 | } | ||
| 190 | try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{}); | ||
| 191 | try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_text_section_index.?, .{}); | ||
| 192 | } | ||
| 193 | |||
| 194 | if (elf_file.zig_data_rel_ro_section_index == null) { | ||
| 195 | elf_file.zig_data_rel_ro_section_index = try elf_file.addSection(.{ | ||
| 196 | .name = try elf_file.insertShString(".data.rel.ro.zig"), | ||
| 197 | .type = elf.SHT_PROGBITS, | ||
| 198 | .addralign = 1, | ||
| 199 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | ||
| 200 | .offset = std.math.maxInt(u64), | ||
| 201 | }); | ||
| 202 | const shdr = &elf_file.shdrs.items[elf_file.zig_data_rel_ro_section_index.?]; | ||
| 203 | try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_ro_index); | ||
| 204 | if (elf_file.base.isRelocatable()) { | ||
| 205 | const rela_shndx = try elf_file.addRelaShdr( | ||
| 206 | try elf_file.insertShString(".rela.data.rel.ro.zig"), | ||
| 207 | elf_file.zig_data_rel_ro_section_index.?, | ||
| 208 | ); | ||
| 209 | try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{ | ||
| 210 | .shndx = rela_shndx, | ||
| 211 | }); | ||
| 212 | } else { | ||
| 213 | try elf_file.phdr_to_shdr_table.putNoClobber( | ||
| 214 | gpa, | ||
| 215 | elf_file.zig_data_rel_ro_section_index.?, | ||
| 216 | elf_file.phdr_zig_load_ro_index.?, | ||
| 217 | ); | ||
| 218 | } | ||
| 219 | try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{}); | ||
| 220 | try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_data_rel_ro_section_index.?, .{}); | ||
| 221 | } | ||
| 222 | |||
| 223 | if (elf_file.zig_data_section_index == null) { | ||
| 224 | elf_file.zig_data_section_index = try elf_file.addSection(.{ | ||
| 225 | .name = try elf_file.insertShString(".data.zig"), | ||
| 226 | .type = elf.SHT_PROGBITS, | ||
| 227 | .addralign = ptr_size, | ||
| 228 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | ||
| 229 | .offset = std.math.maxInt(u64), | ||
| 230 | }); | ||
| 231 | const shdr = &elf_file.shdrs.items[elf_file.zig_data_section_index.?]; | ||
| 232 | try fillSection(elf_file, shdr, 1024, elf_file.phdr_zig_load_rw_index); | ||
| 233 | if (elf_file.base.isRelocatable()) { | ||
| 234 | const rela_shndx = try elf_file.addRelaShdr( | ||
| 235 | try elf_file.insertShString(".rela.data.zig"), | ||
| 236 | elf_file.zig_data_section_index.?, | ||
| 237 | ); | ||
| 238 | try elf_file.output_rela_sections.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{ | ||
| 239 | .shndx = rela_shndx, | ||
| 240 | }); | ||
| 241 | } else { | ||
| 242 | try elf_file.phdr_to_shdr_table.putNoClobber( | ||
| 243 | gpa, | ||
| 244 | elf_file.zig_data_section_index.?, | ||
| 245 | elf_file.phdr_zig_load_rw_index.?, | ||
| 246 | ); | ||
| 247 | } | ||
| 248 | try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{}); | ||
| 249 | try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_data_section_index.?, .{}); | ||
| 250 | } | ||
| 251 | |||
| 252 | if (elf_file.zig_bss_section_index == null) { | ||
| 253 | elf_file.zig_bss_section_index = try elf_file.addSection(.{ | ||
| 254 | .name = try elf_file.insertShString(".bss.zig"), | ||
| 255 | .type = elf.SHT_NOBITS, | ||
| 256 | .addralign = ptr_size, | ||
| 257 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | ||
| 258 | .offset = 0, | ||
| 259 | }); | ||
| 260 | const shdr = &elf_file.shdrs.items[elf_file.zig_bss_section_index.?]; | ||
| 261 | if (elf_file.phdr_zig_load_zerofill_index) |phndx| { | ||
| 262 | const phdr = elf_file.phdrs.items[phndx]; | ||
| 263 | shdr.sh_addr = phdr.p_vaddr; | ||
| 264 | shdr.sh_size = phdr.p_memsz; | ||
| 265 | try elf_file.phdr_to_shdr_table.putNoClobber(gpa, elf_file.zig_bss_section_index.?, phndx); | ||
| 266 | } else { | ||
| 267 | shdr.sh_size = 1024; | ||
| 268 | } | ||
| 269 | try elf_file.output_sections.putNoClobber(gpa, elf_file.zig_bss_section_index.?, .{}); | ||
| 270 | try elf_file.last_atom_and_free_list_table.putNoClobber(gpa, elf_file.zig_bss_section_index.?, .{}); | ||
| 271 | } | ||
| 80 | 272 | ||
| 81 | switch (comp.config.debug_format) { | 273 | switch (comp.config.debug_format) { |
| 82 | .strip => {}, | 274 | .strip => {}, |
| 83 | .dwarf => |v| self.dwarf = Dwarf.init(&elf_file.base, v), | 275 | .dwarf => |v| { |
| 276 | var dwarf = Dwarf.init(&elf_file.base, v); | ||
| 277 | |||
| 278 | const addSectionSymbol = struct { | ||
| 279 | fn addSectionSymbol( | ||
| 280 | zig_object: *ZigObject, | ||
| 281 | alloc: Allocator, | ||
| 282 | name: [:0]const u8, | ||
| 283 | alignment: Atom.Alignment, | ||
| 284 | shndx: u32, | ||
| 285 | ) !Symbol.Index { | ||
| 286 | const name_off = try zig_object.addString(alloc, name); | ||
| 287 | const index = try zig_object.newSymbolWithAtom(alloc, name_off); | ||
| 288 | const sym = zig_object.symbol(index); | ||
| 289 | const esym = &zig_object.symtab.items(.elf_sym)[sym.esym_index]; | ||
| 290 | esym.st_info |= elf.STT_SECTION; | ||
| 291 | const atom_ptr = zig_object.atom(sym.ref.index).?; | ||
| 292 | atom_ptr.alignment = alignment; | ||
| 293 | atom_ptr.output_section_index = shndx; | ||
| 294 | return index; | ||
| 295 | } | ||
| 296 | }.addSectionSymbol; | ||
| 297 | |||
| 298 | if (elf_file.debug_str_section_index == null) { | ||
| 299 | elf_file.debug_str_section_index = try elf_file.addSection(.{ | ||
| 300 | .name = try elf_file.insertShString(".debug_str"), | ||
| 301 | .flags = elf.SHF_MERGE | elf.SHF_STRINGS, | ||
| 302 | .entsize = 1, | ||
| 303 | .type = elf.SHT_PROGBITS, | ||
| 304 | .addralign = 1, | ||
| 305 | }); | ||
| 306 | self.debug_str_section_dirty = true; | ||
| 307 | self.debug_str_index = try addSectionSymbol(self, gpa, ".debug_str", .@"1", elf_file.debug_str_section_index.?); | ||
| 308 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_str_section_index.?, .{}); | ||
| 309 | } | ||
| 310 | |||
| 311 | if (elf_file.debug_info_section_index == null) { | ||
| 312 | elf_file.debug_info_section_index = try elf_file.addSection(.{ | ||
| 313 | .name = try elf_file.insertShString(".debug_info"), | ||
| 314 | .type = elf.SHT_PROGBITS, | ||
| 315 | .addralign = 1, | ||
| 316 | }); | ||
| 317 | self.debug_info_section_dirty = true; | ||
| 318 | self.debug_info_index = try addSectionSymbol(self, gpa, ".debug_info", .@"1", elf_file.debug_info_section_index.?); | ||
| 319 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_info_section_index.?, .{}); | ||
| 320 | } | ||
| 321 | |||
| 322 | if (elf_file.debug_abbrev_section_index == null) { | ||
| 323 | elf_file.debug_abbrev_section_index = try elf_file.addSection(.{ | ||
| 324 | .name = try elf_file.insertShString(".debug_abbrev"), | ||
| 325 | .type = elf.SHT_PROGBITS, | ||
| 326 | .addralign = 1, | ||
| 327 | }); | ||
| 328 | self.debug_abbrev_section_dirty = true; | ||
| 329 | self.debug_abbrev_index = try addSectionSymbol(self, gpa, ".debug_abbrev", .@"1", elf_file.debug_abbrev_section_index.?); | ||
| 330 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_abbrev_section_index.?, .{}); | ||
| 331 | } | ||
| 332 | |||
| 333 | if (elf_file.debug_aranges_section_index == null) { | ||
| 334 | elf_file.debug_aranges_section_index = try elf_file.addSection(.{ | ||
| 335 | .name = try elf_file.insertShString(".debug_aranges"), | ||
| 336 | .type = elf.SHT_PROGBITS, | ||
| 337 | .addralign = 16, | ||
| 338 | }); | ||
| 339 | self.debug_aranges_section_dirty = true; | ||
| 340 | self.debug_aranges_index = try addSectionSymbol(self, gpa, ".debug_aranges", .@"16", elf_file.debug_aranges_section_index.?); | ||
| 341 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_aranges_section_index.?, .{}); | ||
| 342 | } | ||
| 343 | |||
| 344 | if (elf_file.debug_line_section_index == null) { | ||
| 345 | elf_file.debug_line_section_index = try elf_file.addSection(.{ | ||
| 346 | .name = try elf_file.insertShString(".debug_line"), | ||
| 347 | .type = elf.SHT_PROGBITS, | ||
| 348 | .addralign = 1, | ||
| 349 | }); | ||
| 350 | self.debug_line_section_dirty = true; | ||
| 351 | self.debug_line_index = try addSectionSymbol(self, gpa, ".debug_line", .@"1", elf_file.debug_line_section_index.?); | ||
| 352 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_line_section_index.?, .{}); | ||
| 353 | } | ||
| 354 | |||
| 355 | if (elf_file.debug_line_str_section_index == null) { | ||
| 356 | elf_file.debug_line_str_section_index = try elf_file.addSection(.{ | ||
| 357 | .name = try elf_file.insertShString(".debug_line_str"), | ||
| 358 | .flags = elf.SHF_MERGE | elf.SHF_STRINGS, | ||
| 359 | .entsize = 1, | ||
| 360 | .type = elf.SHT_PROGBITS, | ||
| 361 | .addralign = 1, | ||
| 362 | }); | ||
| 363 | self.debug_line_str_section_dirty = true; | ||
| 364 | self.debug_line_str_index = try addSectionSymbol(self, gpa, ".debug_line_str", .@"1", elf_file.debug_line_str_section_index.?); | ||
| 365 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_line_str_section_index.?, .{}); | ||
| 366 | } | ||
| 367 | |||
| 368 | if (elf_file.debug_loclists_section_index == null) { | ||
| 369 | elf_file.debug_loclists_section_index = try elf_file.addSection(.{ | ||
| 370 | .name = try elf_file.insertShString(".debug_loclists"), | ||
| 371 | .type = elf.SHT_PROGBITS, | ||
| 372 | .addralign = 1, | ||
| 373 | }); | ||
| 374 | self.debug_loclists_section_dirty = true; | ||
| 375 | self.debug_loclists_index = try addSectionSymbol(self, gpa, ".debug_loclists", .@"1", elf_file.debug_loclists_section_index.?); | ||
| 376 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_loclists_section_index.?, .{}); | ||
| 377 | } | ||
| 378 | |||
| 379 | if (elf_file.debug_rnglists_section_index == null) { | ||
| 380 | elf_file.debug_rnglists_section_index = try elf_file.addSection(.{ | ||
| 381 | .name = try elf_file.insertShString(".debug_rnglists"), | ||
| 382 | .type = elf.SHT_PROGBITS, | ||
| 383 | .addralign = 1, | ||
| 384 | }); | ||
| 385 | self.debug_rnglists_section_dirty = true; | ||
| 386 | self.debug_rnglists_index = try addSectionSymbol(self, gpa, ".debug_rnglists", .@"1", elf_file.debug_rnglists_section_index.?); | ||
| 387 | try elf_file.output_sections.putNoClobber(gpa, elf_file.debug_rnglists_section_index.?, .{}); | ||
| 388 | } | ||
| 389 | |||
| 390 | try dwarf.initMetadata(); | ||
| 391 | self.dwarf = dwarf; | ||
| 392 | }, | ||
| 84 | .code_view => unreachable, | 393 | .code_view => unreachable, |
| 85 | } | 394 | } |
| 86 | } | 395 | } |
| ... | @@ -446,7 +755,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Atom.Index { | ... | @@ -446,7 +755,7 @@ fn newAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Atom.Index { |
| 446 | return index; | 755 | return index; |
| 447 | } | 756 | } |
| 448 | 757 | ||
| 449 | pub fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Symbol.Index { | 758 | fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name_off: u32) !Symbol.Index { |
| 450 | const atom_index = try self.newAtom(allocator, name_off); | 759 | const atom_index = try self.newAtom(allocator, name_off); |
| 451 | const sym_index = try self.newLocalSymbol(allocator, name_off); | 760 | const sym_index = try self.newLocalSymbol(allocator, name_off); |
| 452 | const sym = self.symbol(sym_index); | 761 | const sym = self.symbol(sym_index); |