| ... | @@ -17,7 +17,6 @@ comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup.Index) = .{}, | ... | @@ -17,7 +17,6 @@ comdat_groups: std.ArrayListUnmanaged(Elf.ComdatGroup.Index) = .{}, |
| 17 | fdes: std.ArrayListUnmanaged(Fde) = .{}, | 17 | fdes: std.ArrayListUnmanaged(Fde) = .{}, |
| 18 | cies: std.ArrayListUnmanaged(Cie) = .{}, | 18 | cies: std.ArrayListUnmanaged(Cie) = .{}, |
| 19 | | 19 | |
| 20 | needs_exec_stack: bool = false, | | |
| 21 | alive: bool = true, | 20 | alive: bool = true, |
| 22 | num_dynrelocs: u32 = 0, | 21 | num_dynrelocs: u32 = 0, |
| 23 | | 22 | |
| ... | @@ -80,12 +79,12 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { | ... | @@ -80,12 +79,12 @@ pub fn parse(self: *Object, elf_file: *Elf) !void { |
| 80 | try self.initAtoms(elf_file); | 79 | try self.initAtoms(elf_file); |
| 81 | try self.initSymtab(elf_file); | 80 | try self.initSymtab(elf_file); |
| 82 | | 81 | |
| 83 | for (self.shdrs.items, 0..) |shdr, i| { | 82 | // for (self.shdrs.items, 0..) |shdr, i| { |
| 84 | const atom = elf_file.atom(self.atoms.items[i]) orelse continue; | 83 | // const atom = elf_file.atom(self.atoms.items[i]) orelse continue; |
| 85 | if (!atom.alive) continue; | 84 | // if (!atom.alive) continue; |
| 86 | if (shdr.sh_type == elf.SHT_X86_64_UNWIND or mem.eql(u8, atom.name(elf_file), ".eh_frame")) | 85 | // 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); | 86 | // try self.parseEhFrame(@as(u16, @intCast(i)), elf_file); |
| 88 | } | 87 | // } |
| 89 | } | 88 | } |
| 90 | | 89 | |
| 91 | fn initAtoms(self: *Object, elf_file: *Elf) !void { | 90 | fn initAtoms(self: *Object, elf_file: *Elf) !void { |
| ... | @@ -148,20 +147,6 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void { | ... | @@ -148,20 +147,6 @@ fn initAtoms(self: *Object, elf_file: *Elf) !void { |
| 148 | else => { | 147 | else => { |
| 149 | const name = self.strings.getAssumeExists(shdr.sh_name); | 148 | const name = self.strings.getAssumeExists(shdr.sh_name); |
| 150 | const shndx = @as(u16, @intCast(i)); | 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 | if (self.skipShdr(shndx, elf_file)) continue; | 150 | if (self.skipShdr(shndx, elf_file)) continue; |
| 166 | try self.addAtom(shdr, shndx, name, elf_file); | 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,6 +172,7 @@ fn addAtom(self: *Object, shdr: elf.Elf64_Shdr, shndx: u16, name: [:0]const u8, |
| 187 | atom.name_offset = try elf_file.strtab.insert(elf_file.base.allocator, name); | 172 | atom.name_offset = try elf_file.strtab.insert(elf_file.base.allocator, name); |
| 188 | atom.file_index = self.index; | 173 | atom.file_index = self.index; |
| 189 | atom.input_section_index = shndx; | 174 | atom.input_section_index = shndx; |
| | 175 | atom.output_section_index = self.getOutputSectionIndex(elf_file, shdr); |
| 190 | atom.alive = true; | 176 | atom.alive = true; |
| 191 | self.atoms.items[shndx] = atom_index; | 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,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 | fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { | 233 | fn skipShdr(self: *Object, index: u16, elf_file: *Elf) bool { |
| | 234 | _ = elf_file; |
| 205 | const shdr = self.shdrs.items[index]; | 235 | const shdr = self.shdrs.items[index]; |
| 206 | const name = self.strings.getAssumeExists(shdr.sh_name); | 236 | const name = self.strings.getAssumeExists(shdr.sh_name); |
| 207 | const ignore = blk: { | 237 | const ignore = blk: { |
| 208 | if (mem.startsWith(u8, name, ".note")) break :blk true; | 238 | if (mem.startsWith(u8, name, ".note")) break :blk true; |
| 209 | if (mem.startsWith(u8, name, ".comment")) break :blk true; | 239 | if (mem.startsWith(u8, name, ".comment")) break :blk true; |
| 210 | if (mem.startsWith(u8, name, ".llvm_addrsig")) break :blk true; | 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 | 241 | if (mem.startsWith(u8, name, ".eh_frame")) break :blk true; |
| 212 | mem.startsWith(u8, name, ".debug")) 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 | break :blk false; | 245 | break :blk false; |
| 214 | }; | 246 | }; |
| 215 | return ignore; | 247 | return ignore; |