| ... | @@ -817,7 +817,7 @@ fn ElfFile(comptime is_64: bool) type { | ... | @@ -817,7 +817,7 @@ fn ElfFile(comptime is_64: bool) type { |
| 817 | // fill-in sections info: | 817 | // fill-in sections info: |
| 818 | // resolve the name | 818 | // resolve the name |
| 819 | // find if a program segment uses the section | 819 | // find if a program segment uses the section |
| 820 | // categorise sections usage (used by program segments, debug datadase, common metadata, symbol table) | 820 | // categorize sections usage (used by program segments, debug datadase, common metadata, symbol table) |
| 821 | for (sections) |*section| { | 821 | for (sections) |*section| { |
| 822 | section.segment = for (program_segments) |*seg| { | 822 | section.segment = for (program_segments) |*seg| { |
| 823 | if (sectionWithinSegment(section.section, seg.*)) break seg; | 823 | if (sectionWithinSegment(section.section, seg.*)) break seg; |
| ... | @@ -836,8 +836,8 @@ fn ElfFile(comptime is_64: bool) type { | ... | @@ -836,8 +836,8 @@ fn ElfFile(comptime is_64: bool) type { |
| 836 | if (std.mem.eql(u8, section.name, ".gnu_debuglink")) break :cat .none; | 836 | if (std.mem.eql(u8, section.name, ".gnu_debuglink")) break :cat .none; |
| 837 | break :cat category_from_program; | 837 | break :cat category_from_program; |
| 838 | }, | 838 | }, |
| 839 | elf.SHT_LOPROC...elf.SHT_HIPROC => .common, // don't strip unkonwn sections | 839 | elf.SHT_LOPROC...elf.SHT_HIPROC => .common, // don't strip unknown sections |
| 840 | elf.SHT_LOUSER...elf.SHT_HIUSER => .common, // don't strip unkonwn sections | 840 | elf.SHT_LOUSER...elf.SHT_HIUSER => .common, // don't strip unknown sections |
| 841 | else => category_from_program, | 841 | else => category_from_program, |
| 842 | }; | 842 | }; |
| 843 | } | 843 | } |
| ... | @@ -846,7 +846,7 @@ fn ElfFile(comptime is_64: bool) type { | ... | @@ -846,7 +846,7 @@ fn ElfFile(comptime is_64: bool) type { |
| 846 | if (header.shstrndx != elf.SHN_UNDEF) | 846 | if (header.shstrndx != elf.SHN_UNDEF) |
| 847 | sections[header.shstrndx].category = .common; // string table for the headers | 847 | sections[header.shstrndx].category = .common; // string table for the headers |
| 848 | | 848 | |
| 849 | // recursive dependencies | 849 | // recursively propagate section categories to their linked sections, so that they are kept together |
| 850 | var dirty: u1 = 1; | 850 | var dirty: u1 = 1; |
| 851 | while (dirty != 0) { | 851 | while (dirty != 0) { |
| 852 | dirty = 0; | 852 | dirty = 0; |
| ... | @@ -856,29 +856,6 @@ fn ElfFile(comptime is_64: bool) type { | ... | @@ -856,29 +856,6 @@ fn ElfFile(comptime is_64: bool) type { |
| 856 | dirty |= ElfFileHelper.propagateCategory(&sections[section.section.sh_link].category, section.category); | 856 | dirty |= ElfFileHelper.propagateCategory(&sections[section.section.sh_link].category, section.category); |
| 857 | if ((section.section.sh_flags & elf.SHF_INFO_LINK) != 0 and section.section.sh_info != elf.SHN_UNDEF) | 857 | if ((section.section.sh_flags & elf.SHF_INFO_LINK) != 0 and section.section.sh_info != elf.SHN_UNDEF) |
| 858 | dirty |= ElfFileHelper.propagateCategory(&sections[section.section.sh_info].category, section.category); | 858 | dirty |= ElfFileHelper.propagateCategory(&sections[section.section.sh_info].category, section.category); |
| 859 | | | |
| 860 | if (section.payload) |data| { | | |
| 861 | switch (section.section.sh_type) { | | |
| 862 | elf.DT_VERSYM => { | | |
| 863 | assert(section.section.sh_entsize == @sizeOf(Elf_Verdef)); | | |
| 864 | const defs = @ptrCast([*]const Elf_Verdef, data)[0 .. @intCast(usize, section.section.sh_size) / @sizeOf(Elf_Verdef)]; | | |
| 865 | for (defs) |def| { | | |
| 866 | if (def.vd_ndx != elf.SHN_UNDEF) | | |
| 867 | dirty |= ElfFileHelper.propagateCategory(&sections[def.vd_ndx].category, section.category); | | |
| 868 | } | | |
| 869 | }, | | |
| 870 | elf.SHT_SYMTAB, elf.SHT_DYNSYM => { | | |
| 871 | assert(section.section.sh_entsize == @sizeOf(Elf_Sym)); | | |
| 872 | const syms = @ptrCast([*]const Elf_Sym, data)[0 .. @intCast(usize, section.section.sh_size) / @sizeOf(Elf_Sym)]; | | |
| 873 | | | |
| 874 | for (syms) |sym| { | | |
| 875 | if (sym.st_shndx != elf.SHN_UNDEF and sym.st_shndx < elf.SHN_LORESERVE) | | |
| 876 | dirty |= ElfFileHelper.propagateCategory(&sections[sym.st_shndx].category, section.category); | | |
| 877 | } | | |
| 878 | }, | | |
| 879 | else => {}, | | |
| 880 | } | | |
| 881 | } | | |
| 882 | } | 859 | } |
| 883 | } | 860 | } |
| 884 | | 861 | |
| ... | @@ -994,6 +971,8 @@ fn ElfFile(comptime is_64: bool) type { | ... | @@ -994,6 +971,8 @@ fn ElfFile(comptime is_64: bool) type { |
| 994 | // this code only supports when they are in increasing file order. | 971 | // this code only supports when they are in increasing file order. |
| 995 | var offset: u64 = eof_offset; | 972 | var offset: u64 = eof_offset; |
| 996 | for (self.sections[1..]) |section| { | 973 | for (self.sections[1..]) |section| { |
| | 974 | if (section.section.sh_type == elf.SHT_NOBITS) |
| | 975 | continue; |
| 997 | if (section.section.sh_offset < offset) { | 976 | if (section.section.sh_offset < offset) { |
| 998 | fatal("zig objcopy: unsuported ELF file", .{}); | 977 | fatal("zig objcopy: unsuported ELF file", .{}); |
| 999 | } | 978 | } |
| ... | @@ -1025,7 +1004,7 @@ fn ElfFile(comptime is_64: bool) type { | ... | @@ -1025,7 +1004,7 @@ fn ElfFile(comptime is_64: bool) type { |
| 1025 | | 1004 | |
| 1026 | const addralign = if (src.sh_addralign == 0 or dest.sh_type == elf.SHT_NOBITS) 1 else src.sh_addralign; | 1005 | const addralign = if (src.sh_addralign == 0 or dest.sh_type == elf.SHT_NOBITS) 1 else src.sh_addralign; |
| 1027 | dest.sh_offset = std.mem.alignForward(Elf_OffSize, eof_offset, addralign); | 1006 | dest.sh_offset = std.mem.alignForward(Elf_OffSize, eof_offset, addralign); |
| 1028 | if (src.sh_offset != dest.sh_offset and section.segment != null and update.action != .empty and dest.sh_type != elf.SHT_NOTE) { | 1007 | if (src.sh_offset != dest.sh_offset and section.segment != null and update.action != .empty and dest.sh_type != elf.SHT_NOTE and dest.sh_type != elf.SHT_NOBITS) { |
| 1029 | if (src.sh_offset > dest.sh_offset) { | 1008 | if (src.sh_offset > dest.sh_offset) { |
| 1030 | dest.sh_offset = src.sh_offset; // add padding to avoid modifing the program segments | 1009 | dest.sh_offset = src.sh_offset; // add padding to avoid modifing the program segments |
| 1031 | } else { | 1010 | } else { |