| ... | ... | @@ -17,7 +17,6 @@ comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup.Index) = .{}, |
| 17 | 17 | fdes: std.ArrayListUnmanaged(Fde) = .{}, |
| 18 | 18 | cies: std.ArrayListUnmanaged(Cie) = .{}, |
| 19 | 19 | |
| 20 | | needs_exec_stack: bool = false, |
| 21 | 20 | alive: bool = true, |
| 22 | 21 | num_dynrelocs: u32 = 0, |
| 23 | 22 | |
| ... | ... | @@ -80,12 +79,12 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { |
| 80 | 79 | try self.initAtoms(elf_file); |
| 81 | 80 | try self.initSymtab(elf_file); |
| 82 | 81 | |
| 83 | | for (self.shdrs.items, 0..) |shdr, i| { |
| 84 | | const atom = elf_file.atom(self.atoms.items[i]) orelse continue; |
| 85 | | if (!atom.alive) continue; |
| 86 | | if (shdr.sh_type == elf.SHT_X86_64_UNWIND or mem.eql(u8, atom.name(elf_file), ".eh_frame")) |
| 87 | | try self.parseEhFrame(@as(u16, @intCast(i)), elf_file); |
| 88 | | } |
| 82 | // for (self.shdrs.items, 0..) |shdr, i| { |
| 83 | // const atom = elf_file.atom(self.atoms.items[i]) orelse continue; |
| 84 | // if (!atom.alive) continue; |
| 85 | // if (shdr.sh_type == elf.SHT_X86_64_UNWIND or mem.eql(u8, atom.name(elf_file), ".eh_frame")) |
| 86 | // try self.parseEhFrame(@as(u16, @intCast(i)), elf_file); |
| 87 | // } |
| 89 | 88 | } |
| 90 | 89 | |
| 91 | 90 | fn initAtoms(self: *Object, elf_file: *Elf) !void { |
| ... | ... | @@ -148,20 +147,6 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void { |
| 148 | 147 | else => { |
| 149 | 148 | const name = self.strings.getAssumeExists(shdr.sh_name); |
| 150 | 149 | const shndx = @as(u16, @intCast(i)); |
| 151 | | |
| 152 | | // if (mem.eql(u8, ".note.GNU-stack", name)) { |
| 153 | | // if (shdr.sh_flags & elf.SHF_EXECINSTR != 0) { |
| 154 | | // if (!elf_file.options.z_execstack or !elf_file.options.z_execstack_if_needed) { |
| 155 | | // elf_file.base.warn( |
| 156 | | // "{}: may cause segmentation fault as this file requested executable stack", |
| 157 | | // .{self.fmtPath()}, |
| 158 | | // ); |
| 159 | | // } |
| 160 | | // self.needs_exec_stack = true; |
| 161 | | // } |
| 162 | | // continue; |
| 163 | | // } |
| 164 | | |
| 165 | 150 | if (self.skipShdr(shndx, elf_file)) continue; |
| 166 | 151 | try self.addAtom(shdr, shndx, name, elf_file); |
| 167 | 152 | }, |
| ... | ... | @@ -187,6 +172,7 @@ fn addAtom(self: *Object, shdr: elf.Elf64_Shdr, shndx: u16, name: [:0]const u8, |
| 187 | 172 | atom.name_offset = try elf_file.strtab.insert(elf_file.base.allocator, name); |
| 188 | 173 | atom.file_index = self.index; |
| 189 | 174 | atom.input_section_index = shndx; |
| 175 | atom.output_section_index = self.getOutputSectionIndex(elf_file, shdr); |
| 190 | 176 | atom.alive = true; |
| 191 | 177 | self.atoms.items[shndx] = atom_index; |
| 192 | 178 | |
| ... | ... | @@ -201,15 +187,61 @@ fn addAtom(self: *Object, shdr: elf.Elf64_Shdr, shndx: u16, name: [:0]const u8, |
| 201 | 187 | } |
| 202 | 188 | } |
| 203 | 189 | |
| 190 | fn getOutputSectionIndex(self: *Object, elf_file: *Elf, shdr: elf.Elf64_Shdr) u16 { |
| 191 | const name = blk: { |
| 192 | const name = self.strings.getAssumeExists(shdr.sh_name); |
| 193 | // if (shdr.sh_flags & elf.SHF_MERGE != 0) break :blk name; |
| 194 | const sh_name_prefixes: []const [:0]const u8 = &.{ |
| 195 | ".text", ".data.rel.ro", ".data", ".rodata", ".bss.rel.ro", ".bss", |
| 196 | ".init_array", ".fini_array", ".tbss", ".tdata", ".gcc_except_table", ".ctors", |
| 197 | ".dtors", ".gnu.warning", |
| 198 | }; |
| 199 | inline for (sh_name_prefixes) |prefix| { |
| 200 | if (std.mem.eql(u8, name, prefix) or std.mem.startsWith(u8, name, prefix ++ ".")) { |
| 201 | break :blk prefix; |
| 202 | } |
| 203 | } |
| 204 | break :blk name; |
| 205 | }; |
| 206 | const @"type" = switch (shdr.sh_type) { |
| 207 | elf.SHT_NULL => unreachable, |
| 208 | elf.SHT_PROGBITS => blk: { |
| 209 | if (std.mem.eql(u8, name, ".init_array") or std.mem.startsWith(u8, name, ".init_array.")) |
| 210 | break :blk elf.SHT_INIT_ARRAY; |
| 211 | if (std.mem.eql(u8, name, ".fini_array") or std.mem.startsWith(u8, name, ".fini_array.")) |
| 212 | break :blk elf.SHT_FINI_ARRAY; |
| 213 | break :blk shdr.sh_type; |
| 214 | }, |
| 215 | elf.SHT_X86_64_UNWIND => elf.SHT_PROGBITS, |
| 216 | else => shdr.sh_type, |
| 217 | }; |
| 218 | const flags = blk: { |
| 219 | const flags = shdr.sh_flags & ~@as(u64, elf.SHF_COMPRESSED | elf.SHF_GROUP | elf.SHF_GNU_RETAIN); |
| 220 | break :blk switch (@"type") { |
| 221 | elf.SHT_INIT_ARRAY, elf.SHT_FINI_ARRAY => flags | elf.SHF_WRITE, |
| 222 | else => flags, |
| 223 | }; |
| 224 | }; |
| 225 | _ = flags; |
| 226 | const out_shndx = elf_file.sectionByName(name) orelse { |
| 227 | log.err("{}: output section {s} not found", .{ self.fmtPath(), name }); |
| 228 | @panic("TODO: missing output section!"); |
| 229 | }; |
| 230 | return out_shndx; |
| 231 | } |
| 232 | |
| 204 | 233 | fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { |
| 234 | _ = elf_file; |
| 205 | 235 | const shdr = self.shdrs.items[index]; |
| 206 | 236 | const name = self.strings.getAssumeExists(shdr.sh_name); |
| 207 | 237 | const ignore = blk: { |
| 208 | 238 | if (mem.startsWith(u8, name, ".note")) break :blk true; |
| 209 | 239 | if (mem.startsWith(u8, name, ".comment")) break :blk true; |
| 210 | 240 | if (mem.startsWith(u8, name, ".llvm_addrsig")) break :blk true; |
| 211 | | if (elf_file.base.options.strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and |
| 212 | | mem.startsWith(u8, name, ".debug")) break :blk true; |
| 241 | if (mem.startsWith(u8, name, ".eh_frame")) break :blk true; |
| 242 | // if (elf_file.base.options.strip and shdr.sh_flags & elf.SHF_ALLOC == 0 and |
| 243 | // mem.startsWith(u8, name, ".debug")) break :blk true; |
| 244 | if (shdr.sh_flags & elf.SHF_ALLOC == 0 and mem.startsWith(u8, name, ".debug")) break :blk true; |
| 213 | 245 | break :blk false; |
| 214 | 246 | }; |
| 215 | 247 | return ignore; |