| author | |
| committer | |
| log | 7a9eba2f8597a94e4a6def62253e9bf5220a46af |
| tree | 67c8a855e014cae8595a05048cb18b610b66a579 |
| parent | d07edfabd6e45a486d1611e357887d01b38db32e |
7 files changed, 252 insertions(+), 44 deletions(-)
src/arch/x86_64/CodeGen.zig+19-3| ... | ... | @@ -125,7 +125,9 @@ const Owner = union(enum) { |
| 125 | 125 | .func_index => |func_index| { |
| 126 | 126 | const mod = ctx.bin_file.options.module.?; |
| 127 | 127 | const decl_index = mod.funcOwnerDeclIndex(func_index); |
| 128 | if (ctx.bin_file.cast(link.File.MachO)) |macho_file| { | |
| 128 | if (ctx.bin_file.cast(link.File.Elf)) |elf_file| { | |
| 129 | return elf_file.getOrCreateMetadataForDecl(decl_index); | |
| 130 | } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| { | |
| 129 | 131 | const atom = try macho_file.getOrCreateAtomForDecl(decl_index); |
| 130 | 132 | return macho_file.getAtom(atom).getSymbolIndex().?; |
| 131 | 133 | } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| { |
| ... | ... | @@ -136,7 +138,10 @@ const Owner = union(enum) { |
| 136 | 138 | } else unreachable; |
| 137 | 139 | }, |
| 138 | 140 | .lazy_sym => |lazy_sym| { |
| 139 | if (ctx.bin_file.cast(link.File.MachO)) |macho_file| { | |
| 141 | if (ctx.bin_file.cast(link.File.Elf)) |elf_file| { | |
| 142 | return elf_file.getOrCreateMetadataForLazySymbol(lazy_sym) catch |err| | |
| 143 | ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); | |
| 144 | } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| { | |
| 140 | 145 | const atom = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err| |
| 141 | 146 | return ctx.fail("{s} creating lazy symbol", .{@errorName(err)}); |
| 142 | 147 | return macho_file.getAtom(atom).getSymbolIndex().?; |
| ... | ... | @@ -8178,7 +8183,18 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 8178 | 8183 | } else if (func_value.getExternFunc(mod)) |extern_func| { |
| 8179 | 8184 | const decl_name = mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name); |
| 8180 | 8185 | const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name); |
| 8181 | if (self.bin_file.cast(link.File.Coff)) |coff_file| { | |
| 8186 | if (self.bin_file.cast(link.File.Elf)) |elf_file| { | |
| 8187 | const atom_index = try self.owner.getSymbolIndex(self); | |
| 8188 | const sym_index = try elf_file.getGlobalSymbol(decl_name, lib_name); | |
| 8189 | _ = try self.addInst(.{ | |
| 8190 | .tag = .call, | |
| 8191 | .ops = .extern_fn_reloc, | |
| 8192 | .data = .{ .reloc = .{ | |
| 8193 | .atom_index = atom_index, | |
| 8194 | .sym_index = sym_index, | |
| 8195 | } }, | |
| 8196 | }); | |
| 8197 | } else if (self.bin_file.cast(link.File.Coff)) |coff_file| { | |
| 8182 | 8198 | const atom_index = try self.owner.getSymbolIndex(self); |
| 8183 | 8199 | const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name); |
| 8184 | 8200 | _ = try self.addInst(.{ |
src/arch/x86_64/Emit.zig+9-1| ... | ... | @@ -41,7 +41,15 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 41 | 41 | .offset = end_offset - 4, |
| 42 | 42 | .length = @as(u5, @intCast(end_offset - start_offset)), |
| 43 | 43 | }), |
| 44 | .linker_extern_fn => |symbol| if (emit.bin_file.cast(link.File.MachO)) |macho_file| { | |
| 44 | .linker_extern_fn => |symbol| if (emit.bin_file.cast(link.File.Elf)) |elf_file| { | |
| 45 | // Add relocation to the decl. | |
| 46 | const atom_ptr = elf_file.symbol(symbol.atom_index).atom(elf_file).?; | |
| 47 | try atom_ptr.addReloc(elf_file, .{ | |
| 48 | .r_offset = end_offset, | |
| 49 | .r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | std.elf.R_X86_64_PLT32, | |
| 50 | .r_addend = -4, | |
| 51 | }); | |
| 52 | } else if (emit.bin_file.cast(link.File.MachO)) |macho_file| { | |
| 45 | 53 | // Add relocation to the decl. |
| 46 | 54 | const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?; |
| 47 | 55 | const target = macho_file.getGlobalByIndex(symbol.sym_index); |
src/link.zig+1-1| ... | ... | @@ -549,7 +549,7 @@ pub const File = struct { |
| 549 | 549 | switch (base.tag) { |
| 550 | 550 | // zig fmt: off |
| 551 | 551 | .coff => return @fieldParentPtr(Coff, "base", base).getGlobalSymbol(name, lib_name), |
| 552 | .elf => unreachable, | |
| 552 | .elf => return @fieldParentPtr(Elf, "base", base).getGlobalSymbol(name, lib_name), | |
| 553 | 553 | .macho => return @fieldParentPtr(MachO, "base", base).getGlobalSymbol(name, lib_name), |
| 554 | 554 | .plan9 => unreachable, |
| 555 | 555 | .spirv => unreachable, |
src/link/Elf.zig+28-5| ... | ... | @@ -302,9 +302,9 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link. |
| 302 | 302 | const vaddr = this_sym.value; |
| 303 | 303 | const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(self).?; |
| 304 | 304 | try parent_atom.addReloc(self, .{ |
| 305 | .target = this_sym_index, | |
| 306 | .offset = reloc_info.offset, | |
| 307 | .addend = reloc_info.addend, | |
| 305 | .r_offset = reloc_info.offset, | |
| 306 | .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | elf.R_X86_64_64, | |
| 307 | .r_addend = reloc_info.addend, | |
| 308 | 308 | }); |
| 309 | 309 | |
| 310 | 310 | return vaddr; |
| ... | ... | @@ -1020,8 +1020,17 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1020 | 1020 | // Beyond this point, everything has been allocated a virtual address and we can resolve |
| 1021 | 1021 | // the relocations. |
| 1022 | 1022 | if (self.zig_module_index) |index| { |
| 1023 | for (self.file(index).?.zig_module.atoms.items) |atom_index| { | |
| 1024 | try self.atom(atom_index).?.resolveRelocs(self); | |
| 1023 | for (self.file(index).?.zig_module.atoms.keys()) |atom_index| { | |
| 1024 | const atom_ptr = self.atom(atom_index).?; | |
| 1025 | if (!atom_ptr.alive) continue; | |
| 1026 | const shdr = &self.shdrs.items[atom_ptr.output_section_index]; | |
| 1027 | const file_offset = shdr.sh_offset + atom_ptr.value - shdr.sh_addr; | |
| 1028 | const code = try gpa.alloc(u8, atom_ptr.size); | |
| 1029 | defer gpa.free(code); | |
| 1030 | const amt = try self.base.file.?.preadAll(code, file_offset); | |
| 1031 | if (amt != code.len) return error.InputOutput; | |
| 1032 | try atom_ptr.resolveRelocs(self, code); | |
| 1033 | try self.base.file.?.pwriteAll(code, file_offset); | |
| 1025 | 1034 | } |
| 1026 | 1035 | } |
| 1027 | 1036 | |
| ... | ... | @@ -2185,6 +2194,7 @@ fn updateDeclCode( |
| 2185 | 2194 | const shdr_index = sym.output_section_index; |
| 2186 | 2195 | |
| 2187 | 2196 | sym.name_offset = try self.strtab.insert(gpa, decl_name); |
| 2197 | atom_ptr.alive = true; | |
| 2188 | 2198 | atom_ptr.name_offset = sym.name_offset; |
| 2189 | 2199 | esym.st_name = sym.name_offset; |
| 2190 | 2200 | esym.st_info |= stt_bits; |
| ... | ... | @@ -2440,6 +2450,7 @@ fn updateLazySymbol(self: *Elf, sym: link.File.LazySymbol, symbol_index: Symbol. |
| 2440 | 2450 | local_esym.st_info |= elf.STT_OBJECT; |
| 2441 | 2451 | local_esym.st_size = code.len; |
| 2442 | 2452 | const atom_ptr = local_sym.atom(self).?; |
| 2453 | atom_ptr.alive = true; | |
| 2443 | 2454 | atom_ptr.name_offset = name_str_index; |
| 2444 | 2455 | atom_ptr.alignment = math.log2_int(u64, required_alignment); |
| 2445 | 2456 | atom_ptr.size = code.len; |
| ... | ... | @@ -2515,6 +2526,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module |
| 2515 | 2526 | local_esym.st_info |= elf.STT_OBJECT; |
| 2516 | 2527 | local_esym.st_size = code.len; |
| 2517 | 2528 | const atom_ptr = local_sym.atom(self).?; |
| 2529 | atom_ptr.alive = true; | |
| 2518 | 2530 | atom_ptr.name_offset = name_str_index; |
| 2519 | 2531 | atom_ptr.alignment = math.log2_int(u64, required_alignment); |
| 2520 | 2532 | atom_ptr.size = code.len; |
| ... | ... | @@ -3374,6 +3386,17 @@ pub fn globalByName(self: *Elf, name: []const u8) ?Symbol.Index { |
| 3374 | 3386 | return self.resolver.get(name_off); |
| 3375 | 3387 | } |
| 3376 | 3388 | |
| 3389 | pub fn getGlobalSymbol(self: *Elf, name: []const u8, lib_name: ?[]const u8) !u32 { | |
| 3390 | _ = lib_name; | |
| 3391 | const gpa = self.base.allocator; | |
| 3392 | const name_off = try self.strtab.insert(gpa, name); | |
| 3393 | const gop = try self.getOrPutGlobal(name_off); | |
| 3394 | if (!gop.found_existing) { | |
| 3395 | try self.unresolved.putNoClobber(gpa, name_off, {}); | |
| 3396 | } | |
| 3397 | return gop.index; | |
| 3398 | } | |
| 3399 | ||
| 3377 | 3400 | fn dumpState(self: *Elf) std.fmt.Formatter(fmtDumpState) { |
| 3378 | 3401 | return .{ .data = self }; |
| 3379 | 3402 | } |
src/link/Elf/Atom.zig+170-22| ... | ... | @@ -26,7 +26,7 @@ relocs_section_index: Index = 0, |
| 26 | 26 | atom_index: Index = 0, |
| 27 | 27 | |
| 28 | 28 | /// Specifies whether this atom is alive or has been garbage collected. |
| 29 | alive: bool = true, | |
| 29 | alive: bool = false, | |
| 30 | 30 | |
| 31 | 31 | /// Specifies if the atom has been visited during garbage collection. |
| 32 | 32 | visited: bool = false, |
| ... | ... | @@ -192,6 +192,7 @@ pub fn free(self: *Atom, elf_file: *Elf) void { |
| 192 | 192 | log.debug("freeAtom {d} ({s})", .{ self.atom_index, self.name(elf_file) }); |
| 193 | 193 | |
| 194 | 194 | const gpa = elf_file.base.allocator; |
| 195 | const zig_module = elf_file.file(self.file_index).?.zig_module; | |
| 195 | 196 | const shndx = self.output_section_index; |
| 196 | 197 | const meta = elf_file.last_atom_and_free_list_table.getPtr(shndx).?; |
| 197 | 198 | const free_list = &meta.free_list; |
| ... | ... | @@ -242,17 +243,18 @@ pub fn free(self: *Atom, elf_file: *Elf) void { |
| 242 | 243 | |
| 243 | 244 | // TODO create relocs free list |
| 244 | 245 | self.freeRelocs(elf_file); |
| 246 | assert(zig_module.atoms.swapRemove(self.atom_index)); | |
| 245 | 247 | self.* = .{}; |
| 246 | 248 | } |
| 247 | 249 | |
| 248 | pub fn relocs(self: Atom, elf_file: *Elf) []const Relocation { | |
| 250 | pub fn relocs(self: Atom, elf_file: *Elf) []const elf.Elf64_Rela { | |
| 249 | 251 | const file_ptr = elf_file.file(self.file_index).?; |
| 250 | 252 | if (file_ptr != .zig_module) @panic("TODO"); |
| 251 | 253 | const zig_module = file_ptr.zig_module; |
| 252 | 254 | return zig_module.relocs.items[self.relocs_section_index].items; |
| 253 | 255 | } |
| 254 | 256 | |
| 255 | pub fn addReloc(self: Atom, elf_file: *Elf, reloc: Relocation) !void { | |
| 257 | pub fn addReloc(self: Atom, elf_file: *Elf, reloc: elf.Elf64_Rela) !void { | |
| 256 | 258 | const gpa = elf_file.base.allocator; |
| 257 | 259 | const file_ptr = elf_file.file(self.file_index).?; |
| 258 | 260 | assert(file_ptr == .zig_module); |
| ... | ... | @@ -269,31 +271,178 @@ pub fn freeRelocs(self: Atom, elf_file: *Elf) void { |
| 269 | 271 | } |
| 270 | 272 | |
| 271 | 273 | /// TODO mark relocs dirty |
| 272 | pub fn resolveRelocs(self: Atom, elf_file: *Elf) !void { | |
| 274 | pub fn resolveRelocs(self: Atom, elf_file: *Elf, code: []u8) !void { | |
| 273 | 275 | relocs_log.debug("0x{x}: {s}", .{ self.value, self.name(elf_file) }); |
| 274 | const shdr = &elf_file.shdrs.items[self.output_section_index]; | |
| 275 | for (self.relocs(elf_file)) |reloc| { | |
| 276 | const target_sym = elf_file.symbol(reloc.target); | |
| 277 | const target_vaddr = target_sym.value + reloc.addend; | |
| 278 | const section_offset = (self.value + reloc.offset) - shdr.sh_addr; | |
| 279 | const file_offset = shdr.sh_offset + section_offset; | |
| 280 | ||
| 281 | relocs_log.debug(" ({x}: [() => 0x{x}] ({s}))", .{ | |
| 282 | reloc.offset, | |
| 283 | target_vaddr, | |
| 284 | target_sym.name(elf_file), | |
| 276 | ||
| 277 | var stream = std.io.fixedBufferStream(code); | |
| 278 | const cwriter = stream.writer(); | |
| 279 | ||
| 280 | for (self.relocs(elf_file)) |rel| { | |
| 281 | const r_type = rel.r_type(); | |
| 282 | if (r_type == elf.R_X86_64_NONE) continue; | |
| 283 | ||
| 284 | const target = elf_file.symbol(rel.r_sym()); | |
| 285 | ||
| 286 | // We will use equation format to resolve relocations: | |
| 287 | // https://intezer.com/blog/malware-analysis/executable-and-linkable-format-101-part-3-relocations/ | |
| 288 | // | |
| 289 | // Address of the source atom. | |
| 290 | const P = @as(i64, @intCast(self.value + rel.r_offset)); | |
| 291 | // Addend from the relocation. | |
| 292 | const A = rel.r_addend; | |
| 293 | // Address of the target symbol - can be address of the symbol within an atom or address of PLT stub. | |
| 294 | const S = @as(i64, @intCast(target.address(.{}, elf_file))); | |
| 295 | // Address of the global offset table. | |
| 296 | const GOT = blk: { | |
| 297 | const shndx = if (elf_file.got_plt_section_index) |shndx| | |
| 298 | shndx | |
| 299 | else if (elf_file.got_section_index) |shndx| | |
| 300 | shndx | |
| 301 | else | |
| 302 | null; | |
| 303 | break :blk if (shndx) |index| @as(i64, @intCast(elf_file.shdrs.items[index].sh_addr)) else 0; | |
| 304 | }; | |
| 305 | // Relative offset to the start of the global offset table. | |
| 306 | const G = @as(i64, @intCast(target.gotAddress(elf_file))) - GOT; | |
| 307 | // // Address of the thread pointer. | |
| 308 | // const TP = @as(i64, @intCast(elf_file.getTpAddress())); | |
| 309 | // // Address of the dynamic thread pointer. | |
| 310 | // const DTP = @as(i64, @intCast(elf_file.getDtpAddress())); | |
| 311 | ||
| 312 | relocs_log.debug(" {s}: {x}: [{x} => {x}] G({x}) ({s})", .{ | |
| 313 | fmtRelocType(r_type), | |
| 314 | rel.r_offset, | |
| 315 | P, | |
| 316 | S + A, | |
| 317 | G + GOT + A, | |
| 318 | target.name(elf_file), | |
| 285 | 319 | }); |
| 286 | 320 | |
| 287 | switch (elf_file.ptr_width) { | |
| 288 | .p32 => try elf_file.base.file.?.pwriteAll( | |
| 289 | std.mem.asBytes(&@as(u32, @intCast(target_vaddr))), | |
| 290 | file_offset, | |
| 291 | ), | |
| 292 | .p64 => try elf_file.base.file.?.pwriteAll(std.mem.asBytes(&target_vaddr), file_offset), | |
| 321 | try stream.seekTo(rel.r_offset); | |
| 322 | ||
| 323 | switch (rel.r_type()) { | |
| 324 | elf.R_X86_64_NONE => unreachable, | |
| 325 | elf.R_X86_64_64 => try cwriter.writeIntLittle(i64, S + A), | |
| 326 | elf.R_X86_64_PLT32 => try cwriter.writeIntLittle(i32, @as(i32, @intCast(S + A - P))), | |
| 327 | else => @panic("TODO"), | |
| 293 | 328 | } |
| 294 | 329 | } |
| 295 | 330 | } |
| 296 | 331 | |
| 332 | pub fn fmtRelocType(r_type: u32) std.fmt.Formatter(formatRelocType) { | |
| 333 | return .{ .data = r_type }; | |
| 334 | } | |
| 335 | ||
| 336 | fn formatRelocType( | |
| 337 | r_type: u32, | |
| 338 | comptime unused_fmt_string: []const u8, | |
| 339 | options: std.fmt.FormatOptions, | |
| 340 | writer: anytype, | |
| 341 | ) !void { | |
| 342 | _ = unused_fmt_string; | |
| 343 | _ = options; | |
| 344 | const str = switch (r_type) { | |
| 345 | elf.R_X86_64_NONE => "R_X86_64_NONE", | |
| 346 | elf.R_X86_64_64 => "R_X86_64_64", | |
| 347 | elf.R_X86_64_PC32 => "R_X86_64_PC32", | |
| 348 | elf.R_X86_64_GOT32 => "R_X86_64_GOT32", | |
| 349 | elf.R_X86_64_PLT32 => "R_X86_64_PLT32", | |
| 350 | elf.R_X86_64_COPY => "R_X86_64_COPY", | |
| 351 | elf.R_X86_64_GLOB_DAT => "R_X86_64_GLOB_DAT", | |
| 352 | elf.R_X86_64_JUMP_SLOT => "R_X86_64_JUMP_SLOT", | |
| 353 | elf.R_X86_64_RELATIVE => "R_X86_64_RELATIVE", | |
| 354 | elf.R_X86_64_GOTPCREL => "R_X86_64_GOTPCREL", | |
| 355 | elf.R_X86_64_32 => "R_X86_64_32", | |
| 356 | elf.R_X86_64_32S => "R_X86_64_32S", | |
| 357 | elf.R_X86_64_16 => "R_X86_64_16", | |
| 358 | elf.R_X86_64_PC16 => "R_X86_64_PC16", | |
| 359 | elf.R_X86_64_8 => "R_X86_64_8", | |
| 360 | elf.R_X86_64_PC8 => "R_X86_64_PC8", | |
| 361 | elf.R_X86_64_DTPMOD64 => "R_X86_64_DTPMOD64", | |
| 362 | elf.R_X86_64_DTPOFF64 => "R_X86_64_DTPOFF64", | |
| 363 | elf.R_X86_64_TPOFF64 => "R_X86_64_TPOFF64", | |
| 364 | elf.R_X86_64_TLSGD => "R_X86_64_TLSGD", | |
| 365 | elf.R_X86_64_TLSLD => "R_X86_64_TLSLD", | |
| 366 | elf.R_X86_64_DTPOFF32 => "R_X86_64_DTPOFF32", | |
| 367 | elf.R_X86_64_GOTTPOFF => "R_X86_64_GOTTPOFF", | |
| 368 | elf.R_X86_64_TPOFF32 => "R_X86_64_TPOFF32", | |
| 369 | elf.R_X86_64_PC64 => "R_X86_64_PC64", | |
| 370 | elf.R_X86_64_GOTOFF64 => "R_X86_64_GOTOFF64", | |
| 371 | elf.R_X86_64_GOTPC32 => "R_X86_64_GOTPC32", | |
| 372 | elf.R_X86_64_GOT64 => "R_X86_64_GOT64", | |
| 373 | elf.R_X86_64_GOTPCREL64 => "R_X86_64_GOTPCREL64", | |
| 374 | elf.R_X86_64_GOTPC64 => "R_X86_64_GOTPC64", | |
| 375 | elf.R_X86_64_GOTPLT64 => "R_X86_64_GOTPLT64", | |
| 376 | elf.R_X86_64_PLTOFF64 => "R_X86_64_PLTOFF64", | |
| 377 | elf.R_X86_64_SIZE32 => "R_X86_64_SIZE32", | |
| 378 | elf.R_X86_64_SIZE64 => "R_X86_64_SIZE64", | |
| 379 | elf.R_X86_64_GOTPC32_TLSDESC => "R_X86_64_GOTPC32_TLSDESC", | |
| 380 | elf.R_X86_64_TLSDESC_CALL => "R_X86_64_TLSDESC_CALL", | |
| 381 | elf.R_X86_64_TLSDESC => "R_X86_64_TLSDESC", | |
| 382 | elf.R_X86_64_IRELATIVE => "R_X86_64_IRELATIVE", | |
| 383 | elf.R_X86_64_RELATIVE64 => "R_X86_64_RELATIVE64", | |
| 384 | elf.R_X86_64_GOTPCRELX => "R_X86_64_GOTPCRELX", | |
| 385 | elf.R_X86_64_REX_GOTPCRELX => "R_X86_64_REX_GOTPCRELX", | |
| 386 | elf.R_X86_64_NUM => "R_X86_64_NUM", | |
| 387 | else => "R_X86_64_UNKNOWN", | |
| 388 | }; | |
| 389 | try writer.print("{s}", .{str}); | |
| 390 | } | |
| 391 | ||
| 392 | pub fn format( | |
| 393 | atom: Atom, | |
| 394 | comptime unused_fmt_string: []const u8, | |
| 395 | options: std.fmt.FormatOptions, | |
| 396 | writer: anytype, | |
| 397 | ) !void { | |
| 398 | _ = atom; | |
| 399 | _ = unused_fmt_string; | |
| 400 | _ = options; | |
| 401 | _ = writer; | |
| 402 | @compileError("do not format symbols directly"); | |
| 403 | } | |
| 404 | ||
| 405 | pub fn fmt(atom: Atom, elf_file: *Elf) std.fmt.Formatter(format2) { | |
| 406 | return .{ .data = .{ | |
| 407 | .atom = atom, | |
| 408 | .elf_file = elf_file, | |
| 409 | } }; | |
| 410 | } | |
| 411 | ||
| 412 | const FormatContext = struct { | |
| 413 | atom: Atom, | |
| 414 | elf_file: *Elf, | |
| 415 | }; | |
| 416 | ||
| 417 | fn format2( | |
| 418 | ctx: FormatContext, | |
| 419 | comptime unused_fmt_string: []const u8, | |
| 420 | options: std.fmt.FormatOptions, | |
| 421 | writer: anytype, | |
| 422 | ) !void { | |
| 423 | _ = options; | |
| 424 | _ = unused_fmt_string; | |
| 425 | const atom = ctx.atom; | |
| 426 | const elf_file = ctx.elf_file; | |
| 427 | try writer.print("atom({d}) : {s} : @{x} : sect({d}) : align({x}) : size({x})", .{ | |
| 428 | atom.atom_index, atom.name(elf_file), atom.value, | |
| 429 | atom.output_section_index, atom.alignment, atom.size, | |
| 430 | }); | |
| 431 | // if (atom.fde_start != atom.fde_end) { | |
| 432 | // try writer.writeAll(" : fdes{ "); | |
| 433 | // for (atom.getFdes(elf_file), atom.fde_start..) |fde, i| { | |
| 434 | // try writer.print("{d}", .{i}); | |
| 435 | // if (!fde.alive) try writer.writeAll("([*])"); | |
| 436 | // if (i < atom.fde_end - 1) try writer.writeAll(", "); | |
| 437 | // } | |
| 438 | // try writer.writeAll(" }"); | |
| 439 | // } | |
| 440 | const gc_sections = if (elf_file.base.options.gc_sections) |gc_sections| gc_sections else false; | |
| 441 | if (gc_sections and !atom.alive) { | |
| 442 | try writer.writeAll(" : [*]"); | |
| 443 | } | |
| 444 | } | |
| 445 | ||
| 297 | 446 | pub const Index = u32; |
| 298 | 447 | |
| 299 | 448 | const std = @import("std"); |
| ... | ... | @@ -306,4 +455,3 @@ const Allocator = std.mem.Allocator; |
| 306 | 455 | const Atom = @This(); |
| 307 | 456 | const Elf = @import("../Elf.zig"); |
| 308 | 457 | const File = @import("file.zig").File; |
| 309 | const Relocation = @import("Relocation.zig"); |
src/link/Elf/Relocation.zig deleted-8| ... | ... | @@ -1,8 +0,0 @@ |
| 1 | target: Symbol.Index, | |
| 2 | offset: u64, | |
| 3 | addend: u32, | |
| 4 | ||
| 5 | const std = @import("std"); | |
| 6 | ||
| 7 | const Symbol = @import("Symbol.zig"); | |
| 8 | const Relocation = @This(); |
src/link/Elf/ZigModule.zig+25-4| ... | ... | @@ -8,8 +8,8 @@ local_symbols: std.AutoArrayHashMapUnmanaged(Symbol.Index, void) = .{}, |
| 8 | 8 | elf_global_symbols: std.ArrayListUnmanaged(elf.Elf64_Sym) = .{}, |
| 9 | 9 | global_symbols: std.AutoArrayHashMapUnmanaged(Symbol.Index, void) = .{}, |
| 10 | 10 | |
| 11 | atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, | |
| 12 | relocs: std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation)) = .{}, | |
| 11 | atoms: std.AutoArrayHashMapUnmanaged(Atom.Index, void) = .{}, | |
| 12 | relocs: std.ArrayListUnmanaged(std.ArrayListUnmanaged(elf.Elf64_Rela)) = .{}, | |
| 13 | 13 | |
| 14 | 14 | alive: bool = true, |
| 15 | 15 | |
| ... | ... | @@ -43,7 +43,7 @@ pub fn createAtom(self: *ZigModule, output_section_index: u16, elf_file: *Elf) ! |
| 43 | 43 | const relocs = try self.relocs.addOne(gpa); |
| 44 | 44 | relocs.* = .{}; |
| 45 | 45 | atom_ptr.relocs_section_index = relocs_index; |
| 46 | try self.atoms.append(gpa, atom_index); | |
| 46 | try self.atoms.putNoClobber(gpa, atom_index, {}); | |
| 47 | 47 | return symbol_index; |
| 48 | 48 | } |
| 49 | 49 | |
| ... | ... | @@ -184,6 +184,28 @@ fn formatSymtab( |
| 184 | 184 | } |
| 185 | 185 | } |
| 186 | 186 | |
| 187 | pub fn fmtAtoms(self: *ZigModule, elf_file: *Elf) std.fmt.Formatter(formatAtoms) { | |
| 188 | return .{ .data = .{ | |
| 189 | .self = self, | |
| 190 | .elf_file = elf_file, | |
| 191 | } }; | |
| 192 | } | |
| 193 | ||
| 194 | fn formatAtoms( | |
| 195 | ctx: FormatContext, | |
| 196 | comptime unused_fmt_string: []const u8, | |
| 197 | options: std.fmt.FormatOptions, | |
| 198 | writer: anytype, | |
| 199 | ) !void { | |
| 200 | _ = unused_fmt_string; | |
| 201 | _ = options; | |
| 202 | try writer.writeAll(" atoms\n"); | |
| 203 | for (ctx.self.atoms.keys()) |atom_index| { | |
| 204 | const atom = ctx.elf_file.atom(atom_index) orelse continue; | |
| 205 | try writer.print(" {}\n", .{atom.fmt(ctx.elf_file)}); | |
| 206 | } | |
| 207 | } | |
| 208 | ||
| 187 | 209 | const assert = std.debug.assert; |
| 188 | 210 | const std = @import("std"); |
| 189 | 211 | const elf = std.elf; |
| ... | ... | @@ -193,6 +215,5 @@ const Atom = @import("Atom.zig"); |
| 193 | 215 | const Elf = @import("../Elf.zig"); |
| 194 | 216 | const File = @import("file.zig").File; |
| 195 | 217 | const Module = @import("../../Module.zig"); |
| 196 | const Relocation = @import("Relocation.zig"); | |
| 197 | 218 | const Symbol = @import("Symbol.zig"); |
| 198 | 219 | const ZigModule = @This(); |