authorgravatar for xavierb@gmail.comXavier Bouchoux <xavierb@gmail.com> 2023-05-12 21:45:23+02:00
committergravatar for xavierb@gmail.comXavier Bouchoux <xavierb@gmail.com> 2023-06-19 07:29:39+02:00
log5eacddce99c36c6f6ab62e7e7e5cc427c3e2f807
treeb6bf137b19b107d355b2bde41d5e81d7f532f902
parent423d7b848b1953173df99fde1f83166dc68c2a2c

objcopy: support some more elf file variants

"SHT_NOBITS" sections can be easily moved around in the file, they can be anywhere since there is no data... and remove logic about the categorization of symbol tables: I don't understand or remember why it was needed, and, in my tests, it works fine without... It previouly failed to strip an exe linked with `mold`

1 files changed, 7 insertions(+), 28 deletions(-)

src/objcopy.zig+7-28
......@@ -817,7 +817,7 @@ fn ElfFile(comptime is_64: bool) type {
817817 // fill-in sections info:
818818 // resolve the name
819819 // 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)
821821 for (sections) |*section| {
822822 section.segment = for (program_segments) |*seg| {
823823 if (sectionWithinSegment(section.section, seg.*)) break seg;
......@@ -836,8 +836,8 @@ fn ElfFile(comptime is_64: bool) type {
836836 if (std.mem.eql(u8, section.name, ".gnu_debuglink")) break :cat .none;
837837 break :cat category_from_program;
838838 },
839 elf.SHT_LOPROC...elf.SHT_HIPROC => .common, // don't strip unkonwn sections
840 elf.SHT_LOUSER...elf.SHT_HIUSER => .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 unknown sections
841841 else => category_from_program,
842842 };
843843 }
......@@ -846,7 +846,7 @@ fn ElfFile(comptime is_64: bool) type {
846846 if (header.shstrndx != elf.SHN_UNDEF)
847847 sections[header.shstrndx].category = .common; // string table for the headers
848848
849 // recursive dependencies
849 // recursively propagate section categories to their linked sections, so that they are kept together
850850 var dirty: u1 = 1;
851851 while (dirty != 0) {
852852 dirty = 0;
......@@ -856,29 +856,6 @@ fn ElfFile(comptime is_64: bool) type {
856856 dirty |= ElfFileHelper.propagateCategory(&sections[section.section.sh_link].category, section.category);
857857 if ((section.section.sh_flags & elf.SHF_INFO_LINK) != 0 and section.section.sh_info != elf.SHN_UNDEF)
858858 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 }
882859 }
883860 }
884861
......@@ -994,6 +971,8 @@ fn ElfFile(comptime is_64: bool) type {
994971 // this code only supports when they are in increasing file order.
995972 var offset: u64 = eof_offset;
996973 for (self.sections[1..]) |section| {
974 if (section.section.sh_type == elf.SHT_NOBITS)
975 continue;
997976 if (section.section.sh_offset < offset) {
998977 fatal("zig objcopy: unsuported ELF file", .{});
999978 }
......@@ -1025,7 +1004,7 @@ fn ElfFile(comptime is_64: bool) type {
10251004
10261005 const addralign = if (src.sh_addralign == 0 or dest.sh_type == elf.SHT_NOBITS) 1 else src.sh_addralign;
10271006 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) {
10291008 if (src.sh_offset > dest.sh_offset) {
10301009 dest.sh_offset = src.sh_offset; // add padding to avoid modifing the program segments
10311010 } else {