| ... | @@ -432,6 +432,60 @@ pub fn updateRelaSectionSizes(self: ZigObject, elf_file: *Elf) void { | ... | @@ -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 | pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index { | 489 | pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index { |
| 436 | const is_global = index & global_symbol_bit != 0; | 490 | const is_global = index & global_symbol_bit != 0; |
| 437 | const actual_index = index & symbol_mask; | 491 | const actual_index = index & symbol_mask; |