| ... | ... | @@ -432,6 +432,60 @@ pub fn updateRelaSectionSizes(self: ZigObject, elf_file: *Elf) void { |
| 432 | 432 | } |
| 433 | 433 | } |
| 434 | 434 | |
| 435 | pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { |
| 436 | _ = self; |
| 437 | const gpa = elf_file.base.allocator; |
| 438 | |
| 439 | for (&[_]?u16{ |
| 440 | elf_file.zig_text_rela_section_index, |
| 441 | elf_file.zig_data_rel_ro_rela_section_index, |
| 442 | elf_file.zig_data_rela_section_index, |
| 443 | }) |maybe_index| { |
| 444 | const index = maybe_index orelse continue; |
| 445 | const shdr = elf_file.shdrs.items[index]; |
| 446 | const meta = elf_file.last_atom_and_free_list_table.get(@intCast(shdr.sh_info)).?; |
| 447 | const last_atom_index = meta.last_atom_index; |
| 448 | |
| 449 | var atom = elf_file.atom(last_atom_index) orelse continue; |
| 450 | |
| 451 | var relocs = std.ArrayList(elf.Elf64_Rela).init(gpa); |
| 452 | defer relocs.deinit(); |
| 453 | try relocs.ensureTotalCapacityPrecise(@divExact(shdr.sh_size, shdr.sh_entsize)); |
| 454 | |
| 455 | while (true) { |
| 456 | for (atom.relocs(elf_file)) |rel| { |
| 457 | relocs.appendAssumeCapacity(switch (rel.r_type()) { |
| 458 | Elf.R_X86_64_ZIG_GOT32 => .{ |
| 459 | .r_offset = rel.r_offset, |
| 460 | .r_addend = rel.r_addend, |
| 461 | .r_info = (@as(u64, @intCast(rel.r_sym())) << 32) | elf.R_X86_64_32, |
| 462 | }, |
| 463 | Elf.R_X86_64_ZIG_GOTPCREL => .{ |
| 464 | .r_offset = rel.r_offset, |
| 465 | .r_addend = rel.r_addend, |
| 466 | .r_info = (@as(u64, @intCast(rel.r_sym())) << 32) | elf.R_X86_64_PC32, |
| 467 | }, |
| 468 | else => rel, |
| 469 | }); |
| 470 | } |
| 471 | if (elf_file.atom(atom.prev_index)) |prev| { |
| 472 | atom = prev; |
| 473 | } else break; |
| 474 | } |
| 475 | |
| 476 | const SortRelocs = struct { |
| 477 | pub fn lessThan(ctx: void, lhs: elf.Elf64_Rela, rhs: elf.Elf64_Rela) bool { |
| 478 | _ = ctx; |
| 479 | return lhs.r_offset < rhs.r_offset; |
| 480 | } |
| 481 | }; |
| 482 | |
| 483 | mem.sort(elf.Elf64_Rela, relocs.items, {}, SortRelocs.lessThan); |
| 484 | |
| 485 | try elf_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset); |
| 486 | } |
| 487 | } |
| 488 | |
| 435 | 489 | pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index { |
| 436 | 490 | const is_global = index & global_symbol_bit != 0; |
| 437 | 491 | const actual_index = index & symbol_mask; |