| author | |
| committer | |
| log | d328140858ab7f0f3eeb5d53b50bae32ab331686 |
| tree | 63881cfb19195a7629ae5ae891837bb96eebbffc |
| parent | 4c2b34e8abd1fc2091eeb10798658bd9bb3910f5 |
8 files changed, 30 insertions(+), 438 deletions(-)
src/arch/x86_64/Emit.zig+12-33| ... | @@ -110,21 +110,11 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -110,21 +110,11 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 110 | }); | 110 | }); |
| 111 | }, | 111 | }, |
| 112 | .linker_reloc => |data| if (emit.lower.bin_file.cast(.elf)) |elf_file| { | 112 | .linker_reloc => |data| if (emit.lower.bin_file.cast(.elf)) |elf_file| { |
| 113 | const is_obj_or_static_lib = switch (emit.lower.output_mode) { | ||
| 114 | .Exe => false, | ||
| 115 | .Obj => true, | ||
| 116 | .Lib => emit.lower.link_mode == .static, | ||
| 117 | }; | ||
| 118 | const zo = elf_file.zigObjectPtr().?; | 113 | const zo = elf_file.zigObjectPtr().?; |
| 119 | const atom = zo.symbol(data.atom_index).atom(elf_file).?; | 114 | const atom = zo.symbol(data.atom_index).atom(elf_file).?; |
| 120 | const sym = zo.symbol(data.sym_index); | 115 | const sym = zo.symbol(data.sym_index); |
| 121 | if (sym.flags.needs_zig_got and !is_obj_or_static_lib) { | ||
| 122 | _ = try sym.getOrCreateZigGotEntry(data.sym_index, elf_file); | ||
| 123 | } | ||
| 124 | if (emit.lower.pic) { | 116 | if (emit.lower.pic) { |
| 125 | const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib) | 117 | const r_type: u32 = if (sym.flags.needs_got) |
| 126 | link.File.Elf.R_ZIG_GOTPCREL | ||
| 127 | else if (sym.flags.needs_got) | ||
| 128 | @intFromEnum(std.elf.R_X86_64.GOTPCREL) | 118 | @intFromEnum(std.elf.R_X86_64.GOTPCREL) |
| 129 | else | 119 | else |
| 130 | @intFromEnum(std.elf.R_X86_64.PC32); | 120 | @intFromEnum(std.elf.R_X86_64.PC32); |
| ... | @@ -134,28 +124,17 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -134,28 +124,17 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 134 | .r_addend = -4, | 124 | .r_addend = -4, |
| 135 | }); | 125 | }); |
| 136 | } else { | 126 | } else { |
| 137 | if (lowered_inst.encoding.mnemonic == .call and sym.flags.needs_zig_got and is_obj_or_static_lib) { | 127 | const r_type: u32 = if (sym.flags.needs_got) |
| 138 | const r_type = @intFromEnum(std.elf.R_X86_64.PC32); | 128 | @intFromEnum(std.elf.R_X86_64.GOT32) |
| 139 | try atom.addReloc(elf_file, .{ | 129 | else if (sym.flags.is_tls) |
| 140 | .r_offset = end_offset - 4, | 130 | @intFromEnum(std.elf.R_X86_64.TPOFF32) |
| 141 | .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type, | 131 | else |
| 142 | .r_addend = -4, | 132 | @intFromEnum(std.elf.R_X86_64.@"32"); |
| 143 | }); | 133 | try atom.addReloc(elf_file, .{ |
| 144 | } else { | 134 | .r_offset = end_offset - 4, |
| 145 | const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib) | 135 | .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type, |
| 146 | link.File.Elf.R_ZIG_GOT32 | 136 | .r_addend = 0, |
| 147 | else if (sym.flags.needs_got) | 137 | }); |
| 148 | @intFromEnum(std.elf.R_X86_64.GOT32) | ||
| 149 | else if (sym.flags.is_tls) | ||
| 150 | @intFromEnum(std.elf.R_X86_64.TPOFF32) | ||
| 151 | else | ||
| 152 | @intFromEnum(std.elf.R_X86_64.@"32"); | ||
| 153 | try atom.addReloc(elf_file, .{ | ||
| 154 | .r_offset = end_offset - 4, | ||
| 155 | .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type, | ||
| 156 | .r_addend = 0, | ||
| 157 | }); | ||
| 158 | } | ||
| 159 | } | 138 | } |
| 160 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { | 139 | } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { |
| 161 | const is_obj_or_static_lib = switch (emit.lower.output_mode) { | 140 | const is_obj_or_static_lib = switch (emit.lower.output_mode) { |
src/arch/x86_64/Lower.zig+6-16| ... | @@ -398,30 +398,20 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) | ... | @@ -398,30 +398,20 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) |
| 398 | 398 | ||
| 399 | _ = lower.reloc(.{ .linker_reloc = sym }); | 399 | _ = lower.reloc(.{ .linker_reloc = sym }); |
| 400 | break :op if (lower.pic) switch (mnemonic) { | 400 | break :op if (lower.pic) switch (mnemonic) { |
| 401 | .lea => { | 401 | .lea => break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) }, |
| 402 | break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) }; | 402 | .mov => break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) }, |
| 403 | }, | ||
| 404 | .mov => { | ||
| 405 | if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) emit_mnemonic = .lea; | ||
| 406 | break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) }; | ||
| 407 | }, | ||
| 408 | else => unreachable, | 403 | else => unreachable, |
| 409 | } else switch (mnemonic) { | 404 | } else switch (mnemonic) { |
| 410 | .call => break :op if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) .{ | 405 | .call => break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ |
| 411 | .imm = Immediate.s(0), | ||
| 412 | } else .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ | ||
| 413 | .base = .{ .reg = .ds }, | 406 | .base = .{ .reg = .ds }, |
| 414 | }) }, | 407 | }) }, |
| 415 | .lea => { | 408 | .lea => { |
| 416 | emit_mnemonic = .mov; | 409 | emit_mnemonic = .mov; |
| 417 | break :op .{ .imm = Immediate.s(0) }; | 410 | break :op .{ .imm = Immediate.s(0) }; |
| 418 | }, | 411 | }, |
| 419 | .mov => { | 412 | .mov => break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ |
| 420 | if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) emit_mnemonic = .lea; | 413 | .base = .{ .reg = .ds }, |
| 421 | break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ | 414 | }) }, |
| 422 | .base = .{ .reg = .ds }, | ||
| 423 | }) }; | ||
| 424 | }, | ||
| 425 | else => unreachable, | 415 | else => unreachable, |
| 426 | }; | 416 | }; |
| 427 | } else if (lower.bin_file.cast(.macho)) |macho_file| { | 417 | } else if (lower.bin_file.cast(.macho)) |macho_file| { |
src/link/Elf.zig+3-75| ... | @@ -64,9 +64,6 @@ phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{}, | ... | @@ -64,9 +64,6 @@ phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{}, |
| 64 | /// Tracked loadable segments during incremental linking. | 64 | /// Tracked loadable segments during incremental linking. |
| 65 | /// The index into the program headers of a PT_LOAD program header with Read and Execute flags | 65 | /// The index into the program headers of a PT_LOAD program header with Read and Execute flags |
| 66 | phdr_zig_load_re_index: ?u16 = null, | 66 | phdr_zig_load_re_index: ?u16 = null, |
| 67 | /// The index into the program headers of the global offset table. | ||
| 68 | /// It needs PT_LOAD and Read flags. | ||
| 69 | phdr_zig_got_index: ?u16 = null, | ||
| 70 | /// The index into the program headers of a PT_LOAD program header with Read flag | 67 | /// The index into the program headers of a PT_LOAD program header with Read flag |
| 71 | phdr_zig_load_ro_index: ?u16 = null, | 68 | phdr_zig_load_ro_index: ?u16 = null, |
| 72 | /// The index into the program headers of a PT_LOAD program header with Write flag | 69 | /// The index into the program headers of a PT_LOAD program header with Write flag |
| ... | @@ -130,8 +127,6 @@ plt_got: PltGotSection = .{}, | ... | @@ -130,8 +127,6 @@ plt_got: PltGotSection = .{}, |
| 130 | copy_rel: CopyRelSection = .{}, | 127 | copy_rel: CopyRelSection = .{}, |
| 131 | /// .rela.plt section | 128 | /// .rela.plt section |
| 132 | rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, | 129 | rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, |
| 133 | /// .got.zig section | ||
| 134 | zig_got: ZigGotSection = .{}, | ||
| 135 | /// SHT_GROUP sections | 130 | /// SHT_GROUP sections |
| 136 | /// Applies only to a relocatable. | 131 | /// Applies only to a relocatable. |
| 137 | comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{}, | 132 | comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{}, |
| ... | @@ -142,7 +137,6 @@ zig_text_section_index: ?u32 = null, | ... | @@ -142,7 +137,6 @@ zig_text_section_index: ?u32 = null, |
| 142 | zig_data_rel_ro_section_index: ?u32 = null, | 137 | zig_data_rel_ro_section_index: ?u32 = null, |
| 143 | zig_data_section_index: ?u32 = null, | 138 | zig_data_section_index: ?u32 = null, |
| 144 | zig_bss_section_index: ?u32 = null, | 139 | zig_bss_section_index: ?u32 = null, |
| 145 | zig_got_section_index: ?u32 = null, | ||
| 146 | 140 | ||
| 147 | debug_info_section_index: ?u32 = null, | 141 | debug_info_section_index: ?u32 = null, |
| 148 | debug_abbrev_section_index: ?u32 = null, | 142 | debug_abbrev_section_index: ?u32 = null, |
| ... | @@ -474,7 +468,6 @@ pub fn deinit(self: *Elf) void { | ... | @@ -474,7 +468,6 @@ pub fn deinit(self: *Elf) void { |
| 474 | self.copy_rel.deinit(gpa); | 468 | self.copy_rel.deinit(gpa); |
| 475 | self.rela_dyn.deinit(gpa); | 469 | self.rela_dyn.deinit(gpa); |
| 476 | self.rela_plt.deinit(gpa); | 470 | self.rela_plt.deinit(gpa); |
| 477 | self.zig_got.deinit(gpa); | ||
| 478 | self.comdat_group_sections.deinit(gpa); | 471 | self.comdat_group_sections.deinit(gpa); |
| 479 | } | 472 | } |
| 480 | 473 | ||
| ... | @@ -618,21 +611,6 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -618,21 +611,6 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 618 | }); | 611 | }); |
| 619 | } | 612 | } |
| 620 | 613 | ||
| 621 | if (self.phdr_zig_got_index == null) { | ||
| 622 | const alignment = self.page_size; | ||
| 623 | const filesz = @as(u64, ptr_size) * options.symbol_count_hint; | ||
| 624 | const off = self.findFreeSpace(filesz, alignment); | ||
| 625 | self.phdr_zig_got_index = try self.addPhdr(.{ | ||
| 626 | .type = elf.PT_LOAD, | ||
| 627 | .offset = off, | ||
| 628 | .filesz = filesz, | ||
| 629 | .addr = if (ptr_bit_width >= 32) 0x4000000 else 0x4000, | ||
| 630 | .memsz = filesz, | ||
| 631 | .@"align" = alignment, | ||
| 632 | .flags = elf.PF_R | elf.PF_W, | ||
| 633 | }); | ||
| 634 | } | ||
| 635 | |||
| 636 | if (self.phdr_zig_load_ro_index == null) { | 614 | if (self.phdr_zig_load_ro_index == null) { |
| 637 | const alignment = self.page_size; | 615 | const alignment = self.page_size; |
| 638 | const filesz: u64 = 1024; | 616 | const filesz: u64 = 1024; |
| ... | @@ -701,27 +679,6 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { | ... | @@ -701,27 +679,6 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { |
| 701 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{}); | 679 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{}); |
| 702 | } | 680 | } |
| 703 | 681 | ||
| 704 | if (self.zig_got_section_index == null and !self.base.isRelocatable()) { | ||
| 705 | self.zig_got_section_index = try self.addSection(.{ | ||
| 706 | .name = try self.insertShString(".got.zig"), | ||
| 707 | .type = elf.SHT_PROGBITS, | ||
| 708 | .addralign = ptr_size, | ||
| 709 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | ||
| 710 | .offset = std.math.maxInt(u64), | ||
| 711 | }); | ||
| 712 | const shdr = &self.shdrs.items[self.zig_got_section_index.?]; | ||
| 713 | const phndx = self.phdr_zig_got_index.?; | ||
| 714 | const phdr = self.phdrs.items[phndx]; | ||
| 715 | shdr.sh_addr = phdr.p_vaddr; | ||
| 716 | shdr.sh_offset = phdr.p_offset; | ||
| 717 | shdr.sh_size = phdr.p_memsz; | ||
| 718 | try self.phdr_to_shdr_table.putNoClobber( | ||
| 719 | gpa, | ||
| 720 | self.zig_got_section_index.?, | ||
| 721 | self.phdr_zig_got_index.?, | ||
| 722 | ); | ||
| 723 | } | ||
| 724 | |||
| 725 | if (self.zig_data_rel_ro_section_index == null) { | 682 | if (self.zig_data_rel_ro_section_index == null) { |
| 726 | self.zig_data_rel_ro_section_index = try self.addSection(.{ | 683 | self.zig_data_rel_ro_section_index = try self.addSection(.{ |
| 727 | .name = try self.insertShString(".data.rel.ro.zig"), | 684 | .name = try self.insertShString(".data.rel.ro.zig"), |
| ... | @@ -3156,8 +3113,8 @@ fn initSyntheticSections(self: *Elf) !void { | ... | @@ -3156,8 +3113,8 @@ fn initSyntheticSections(self: *Elf) !void { |
| 3156 | }); | 3113 | }); |
| 3157 | 3114 | ||
| 3158 | const needs_rela_dyn = blk: { | 3115 | const needs_rela_dyn = blk: { |
| 3159 | if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or | 3116 | if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or self.copy_rel.symbols.items.len > 0) |
| 3160 | self.zig_got.flags.needs_rela or self.copy_rel.symbols.items.len > 0) break :blk true; | 3117 | break :blk true; |
| 3161 | if (self.zigObjectPtr()) |zig_object| { | 3118 | if (self.zigObjectPtr()) |zig_object| { |
| 3162 | if (zig_object.num_dynrelocs > 0) break :blk true; | 3119 | if (zig_object.num_dynrelocs > 0) break :blk true; |
| 3163 | } | 3120 | } |
| ... | @@ -3562,7 +3519,6 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void { | ... | @@ -3562,7 +3519,6 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void { |
| 3562 | 3519 | ||
| 3563 | for (&[_]*?u16{ | 3520 | for (&[_]*?u16{ |
| 3564 | &self.phdr_zig_load_re_index, | 3521 | &self.phdr_zig_load_re_index, |
| 3565 | &self.phdr_zig_got_index, | ||
| 3566 | &self.phdr_zig_load_ro_index, | 3522 | &self.phdr_zig_load_ro_index, |
| 3567 | &self.phdr_zig_load_zerofill_index, | 3523 | &self.phdr_zig_load_zerofill_index, |
| 3568 | &self.phdr_table_index, | 3524 | &self.phdr_table_index, |
| ... | @@ -3694,7 +3650,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { | ... | @@ -3694,7 +3650,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { |
| 3694 | &self.versym_section_index, | 3650 | &self.versym_section_index, |
| 3695 | &self.verneed_section_index, | 3651 | &self.verneed_section_index, |
| 3696 | &self.zig_text_section_index, | 3652 | &self.zig_text_section_index, |
| 3697 | &self.zig_got_section_index, | ||
| 3698 | &self.zig_data_rel_ro_section_index, | 3653 | &self.zig_data_rel_ro_section_index, |
| 3699 | &self.zig_data_section_index, | 3654 | &self.zig_data_section_index, |
| 3700 | &self.zig_bss_section_index, | 3655 | &self.zig_bss_section_index, |
| ... | @@ -3893,7 +3848,7 @@ fn updateSectionSizes(self: *Elf) !void { | ... | @@ -3893,7 +3848,7 @@ fn updateSectionSizes(self: *Elf) !void { |
| 3893 | } | 3848 | } |
| 3894 | 3849 | ||
| 3895 | if (self.rela_dyn_section_index) |shndx| { | 3850 | if (self.rela_dyn_section_index) |shndx| { |
| 3896 | var num = self.got.numRela(self) + self.copy_rel.numRela() + self.zig_got.numRela(); | 3851 | var num = self.got.numRela(self) + self.copy_rel.numRela(); |
| 3897 | if (self.zigObjectPtr()) |zig_object| { | 3852 | if (self.zigObjectPtr()) |zig_object| { |
| 3898 | num += zig_object.num_dynrelocs; | 3853 | num += zig_object.num_dynrelocs; |
| 3899 | } | 3854 | } |
| ... | @@ -4431,15 +4386,6 @@ pub fn updateSymtabSize(self: *Elf) !void { | ... | @@ -4431,15 +4386,6 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4431 | strsize += ctx.strsize; | 4386 | strsize += ctx.strsize; |
| 4432 | } | 4387 | } |
| 4433 | 4388 | ||
| 4434 | if (self.zigObjectPtr()) |_| { | ||
| 4435 | if (self.zig_got_section_index) |_| { | ||
| 4436 | self.zig_got.output_symtab_ctx.ilocal = nlocals + 1; | ||
| 4437 | self.zig_got.updateSymtabSize(self); | ||
| 4438 | nlocals += self.zig_got.output_symtab_ctx.nlocals; | ||
| 4439 | strsize += self.zig_got.output_symtab_ctx.strsize; | ||
| 4440 | } | ||
| 4441 | } | ||
| 4442 | |||
| 4443 | if (self.got_section_index) |_| { | 4389 | if (self.got_section_index) |_| { |
| 4444 | self.got.output_symtab_ctx.ilocal = nlocals + 1; | 4390 | self.got.output_symtab_ctx.ilocal = nlocals + 1; |
| 4445 | self.got.updateSymtabSize(self); | 4391 | self.got.updateSymtabSize(self); |
| ... | @@ -4576,9 +4522,6 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4576,9 +4522,6 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4576 | const shdr = self.shdrs.items[shndx]; | 4522 | const shdr = self.shdrs.items[shndx]; |
| 4577 | try self.got.addRela(self); | 4523 | try self.got.addRela(self); |
| 4578 | try self.copy_rel.addRela(self); | 4524 | try self.copy_rel.addRela(self); |
| 4579 | if (self.zigObjectPtr()) |_| { | ||
| 4580 | try self.zig_got.addRela(self); | ||
| 4581 | } | ||
| 4582 | self.sortRelaDyn(); | 4525 | self.sortRelaDyn(); |
| 4583 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset); | 4526 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset); |
| 4584 | } | 4527 | } |
| ... | @@ -4674,10 +4617,6 @@ pub fn writeSymtab(self: *Elf) !void { | ... | @@ -4674,10 +4617,6 @@ pub fn writeSymtab(self: *Elf) !void { |
| 4674 | obj.asFile().writeSymtab(self); | 4617 | obj.asFile().writeSymtab(self); |
| 4675 | } | 4618 | } |
| 4676 | 4619 | ||
| 4677 | if (self.zig_got_section_index) |_| { | ||
| 4678 | self.zig_got.writeSymtab(self); | ||
| 4679 | } | ||
| 4680 | |||
| 4681 | if (self.got_section_index) |_| { | 4620 | if (self.got_section_index) |_| { |
| 4682 | self.got.writeSymtab(self); | 4621 | self.got.writeSymtab(self); |
| 4683 | } | 4622 | } |
| ... | @@ -5085,7 +5024,6 @@ pub fn isZigSection(self: Elf, shndx: u32) bool { | ... | @@ -5085,7 +5024,6 @@ pub fn isZigSection(self: Elf, shndx: u32) bool { |
| 5085 | self.zig_data_rel_ro_section_index, | 5024 | self.zig_data_rel_ro_section_index, |
| 5086 | self.zig_data_section_index, | 5025 | self.zig_data_section_index, |
| 5087 | self.zig_bss_section_index, | 5026 | self.zig_bss_section_index, |
| 5088 | self.zig_got_section_index, | ||
| 5089 | }) |maybe_index| { | 5027 | }) |maybe_index| { |
| 5090 | if (maybe_index) |index| { | 5028 | if (maybe_index) |index| { |
| 5091 | if (index == shndx) return true; | 5029 | if (index == shndx) return true; |
| ... | @@ -5704,7 +5642,6 @@ fn fmtDumpState( | ... | @@ -5704,7 +5642,6 @@ fn fmtDumpState( |
| 5704 | } | 5642 | } |
| 5705 | } | 5643 | } |
| 5706 | 5644 | ||
| 5707 | try writer.print("{}\n", .{self.zig_got.fmt(self)}); | ||
| 5708 | try writer.print("{}\n", .{self.got.fmt(self)}); | 5645 | try writer.print("{}\n", .{self.got.fmt(self)}); |
| 5709 | try writer.print("{}\n", .{self.plt.fmt(self)}); | 5646 | try writer.print("{}\n", .{self.plt.fmt(self)}); |
| 5710 | 5647 | ||
| ... | @@ -5995,20 +5932,12 @@ const RelaSection = struct { | ... | @@ -5995,20 +5932,12 @@ const RelaSection = struct { |
| 5995 | }; | 5932 | }; |
| 5996 | const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); | 5933 | const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); |
| 5997 | 5934 | ||
| 5998 | pub const R_ZIG_GOT32: u32 = 0xff00; | ||
| 5999 | pub const R_ZIG_GOTPCREL: u32 = 0xff01; | ||
| 6000 | pub const R_ZIG_GOT_HI20: u32 = 0xff02; | ||
| 6001 | pub const R_ZIG_GOT_LO12: u32 = 0xff03; | ||
| 6002 | pub const R_GOT_HI20_STATIC: u32 = 0xff04; | 5935 | pub const R_GOT_HI20_STATIC: u32 = 0xff04; |
| 6003 | pub const R_GOT_LO12_I_STATIC: u32 = 0xff05; | 5936 | pub const R_GOT_LO12_I_STATIC: u32 = 0xff05; |
| 6004 | 5937 | ||
| 6005 | // Comptime asserts that no Zig relocs overlap with another ISA's reloc number | 5938 | // Comptime asserts that no Zig relocs overlap with another ISA's reloc number |
| 6006 | comptime { | 5939 | comptime { |
| 6007 | const zig_relocs = .{ | 5940 | const zig_relocs = .{ |
| 6008 | R_ZIG_GOT32, | ||
| 6009 | R_ZIG_GOT_HI20, | ||
| 6010 | R_ZIG_GOT_LO12, | ||
| 6011 | R_ZIG_GOTPCREL, | ||
| 6012 | R_GOT_HI20_STATIC, | 5941 | R_GOT_HI20_STATIC, |
| 6013 | R_GOT_LO12_I_STATIC, | 5942 | R_GOT_LO12_I_STATIC, |
| 6014 | }; | 5943 | }; |
| ... | @@ -6099,6 +6028,5 @@ const StringTable = @import("StringTable.zig"); | ... | @@ -6099,6 +6028,5 @@ const StringTable = @import("StringTable.zig"); |
| 6099 | const Thunk = thunks.Thunk; | 6028 | const Thunk = thunks.Thunk; |
| 6100 | const Value = @import("../Value.zig"); | 6029 | const Value = @import("../Value.zig"); |
| 6101 | const VerneedSection = synthetic_sections.VerneedSection; | 6030 | const VerneedSection = synthetic_sections.VerneedSection; |
| 6102 | const ZigGotSection = synthetic_sections.ZigGotSection; | ||
| 6103 | const ZigObject = @import("Elf/ZigObject.zig"); | 6031 | const ZigObject = @import("Elf/ZigObject.zig"); |
| 6104 | const riscv = @import("riscv.zig"); | 6032 | const riscv = @import("riscv.zig"); |
src/link/Elf/Atom.zig+8-41| ... | @@ -750,8 +750,8 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi | ... | @@ -750,8 +750,8 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi |
| 750 | const S = target.address(.{}, elf_file); | 750 | const S = target.address(.{}, elf_file); |
| 751 | // Address of the global offset table. | 751 | // Address of the global offset table. |
| 752 | const GOT = elf_file.gotAddress(); | 752 | const GOT = elf_file.gotAddress(); |
| 753 | // Address of the .zig.got table entry if any. | 753 | // Address of the offset table entry if any. |
| 754 | const ZIG_GOT = target.zigGotAddress(elf_file); | 754 | const ZIG_GOT = target.zigOffsetTableAddress(elf_file); |
| 755 | // Relative offset to the start of the global offset table. | 755 | // Relative offset to the start of the global offset table. |
| 756 | const G = target.gotAddress(elf_file) - GOT; | 756 | const G = target.gotAddress(elf_file) - GOT; |
| 757 | // // Address of the thread pointer. | 757 | // // Address of the thread pointer. |
| ... | @@ -759,14 +759,13 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi | ... | @@ -759,14 +759,13 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi |
| 759 | // Address of the dynamic thread pointer. | 759 | // Address of the dynamic thread pointer. |
| 760 | const DTP = elf_file.dtpAddress(); | 760 | const DTP = elf_file.dtpAddress(); |
| 761 | 761 | ||
| 762 | relocs_log.debug(" {s}: {x}: [{x} => {x}] G({x}) ZG({x}) ZG2({x}) ({s})", .{ | 762 | relocs_log.debug(" {s}: {x}: [{x} => {x}] G({x}) ZG({x}) ({s})", .{ |
| 763 | relocation.fmtRelocType(rel.r_type(), cpu_arch), | 763 | relocation.fmtRelocType(rel.r_type(), cpu_arch), |
| 764 | r_offset, | 764 | r_offset, |
| 765 | P, | 765 | P, |
| 766 | S + A, | 766 | S + A, |
| 767 | G + GOT + A, | 767 | G + GOT + A, |
| 768 | ZIG_GOT + A, | 768 | ZIG_GOT + A, |
| 769 | target.zigOffsetTableAddress(elf_file) + A, | ||
| 770 | target.name(elf_file), | 769 | target.name(elf_file), |
| 771 | }); | 770 | }); |
| 772 | 771 | ||
| ... | @@ -1181,16 +1180,7 @@ const x86_64 = struct { | ... | @@ -1181,16 +1180,7 @@ const x86_64 = struct { |
| 1181 | .TLSDESC_CALL, | 1180 | .TLSDESC_CALL, |
| 1182 | => {}, | 1181 | => {}, |
| 1183 | 1182 | ||
| 1184 | else => |x| switch (@intFromEnum(x)) { | 1183 | else => try atom.reportUnhandledRelocError(rel, elf_file), |
| 1185 | // Zig custom relocations | ||
| 1186 | Elf.R_ZIG_GOT32, | ||
| 1187 | Elf.R_ZIG_GOTPCREL, | ||
| 1188 | => { | ||
| 1189 | assert(symbol.flags.has_zig_got); | ||
| 1190 | }, | ||
| 1191 | |||
| 1192 | else => try atom.reportUnhandledRelocError(rel, elf_file), | ||
| 1193 | }, | ||
| 1194 | } | 1184 | } |
| 1195 | } | 1185 | } |
| 1196 | 1186 | ||
| ... | @@ -1228,7 +1218,7 @@ const x86_64 = struct { | ... | @@ -1228,7 +1218,7 @@ const x86_64 = struct { |
| 1228 | .PLT32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little), | 1218 | .PLT32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little), |
| 1229 | 1219 | ||
| 1230 | .PC32 => { | 1220 | .PC32 => { |
| 1231 | const S_ = if (target.flags.zig_offset_table) target.zigOffsetTableAddress(elf_file) else S; | 1221 | const S_ = if (target.flags.zig_offset_table) ZIG_GOT else S; |
| 1232 | try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little); | 1222 | try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little); |
| 1233 | }, | 1223 | }, |
| 1234 | 1224 | ||
| ... | @@ -1255,7 +1245,7 @@ const x86_64 = struct { | ... | @@ -1255,7 +1245,7 @@ const x86_64 = struct { |
| 1255 | }, | 1245 | }, |
| 1256 | 1246 | ||
| 1257 | .@"32" => { | 1247 | .@"32" => { |
| 1258 | const S_ = if (target.flags.zig_offset_table) target.zigOffsetTableAddress(elf_file) else S; | 1248 | const S_ = if (target.flags.zig_offset_table) ZIG_GOT else S; |
| 1259 | try cwriter.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S_ + A)))), .little); | 1249 | try cwriter.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S_ + A)))), .little); |
| 1260 | }, | 1250 | }, |
| 1261 | .@"32S" => try cwriter.writeInt(i32, @as(i32, @truncate(S + A)), .little), | 1251 | .@"32S" => try cwriter.writeInt(i32, @as(i32, @truncate(S + A)), .little), |
| ... | @@ -1336,13 +1326,7 @@ const x86_64 = struct { | ... | @@ -1336,13 +1326,7 @@ const x86_64 = struct { |
| 1336 | 1326 | ||
| 1337 | .GOT32 => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A)), .little), | 1327 | .GOT32 => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A)), .little), |
| 1338 | 1328 | ||
| 1339 | else => |x| switch (@intFromEnum(x)) { | 1329 | else => try atom.reportUnhandledRelocError(rel, elf_file), |
| 1340 | // Zig custom relocations | ||
| 1341 | Elf.R_ZIG_GOT32 => try cwriter.writeInt(u32, @as(u32, @intCast(ZIG_GOT + A)), .little), | ||
| 1342 | Elf.R_ZIG_GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(ZIG_GOT + A - P)), .little), | ||
| 1343 | |||
| 1344 | else => try atom.reportUnhandledRelocError(rel, elf_file), | ||
| 1345 | }, | ||
| 1346 | } | 1330 | } |
| 1347 | } | 1331 | } |
| 1348 | 1332 | ||
| ... | @@ -2006,12 +1990,6 @@ const riscv = struct { | ... | @@ -2006,12 +1990,6 @@ const riscv = struct { |
| 2006 | => {}, | 1990 | => {}, |
| 2007 | 1991 | ||
| 2008 | else => |x| switch (@intFromEnum(x)) { | 1992 | else => |x| switch (@intFromEnum(x)) { |
| 2009 | Elf.R_ZIG_GOT_HI20, | ||
| 2010 | Elf.R_ZIG_GOT_LO12, | ||
| 2011 | => { | ||
| 2012 | assert(symbol.flags.has_zig_got); | ||
| 2013 | }, | ||
| 2014 | |||
| 2015 | Elf.R_GOT_HI20_STATIC, | 1993 | Elf.R_GOT_HI20_STATIC, |
| 2016 | Elf.R_GOT_LO12_I_STATIC, | 1994 | Elf.R_GOT_LO12_I_STATIC, |
| 2017 | => symbol.flags.needs_got = true, | 1995 | => symbol.flags.needs_got = true, |
| ... | @@ -2038,6 +2016,7 @@ const riscv = struct { | ... | @@ -2038,6 +2016,7 @@ const riscv = struct { |
| 2038 | const P, const A, const S, const GOT, const G, const TP, const DTP, const ZIG_GOT = args; | 2016 | const P, const A, const S, const GOT, const G, const TP, const DTP, const ZIG_GOT = args; |
| 2039 | _ = TP; | 2017 | _ = TP; |
| 2040 | _ = DTP; | 2018 | _ = DTP; |
| 2019 | _ = ZIG_GOT; | ||
| 2041 | 2020 | ||
| 2042 | switch (r_type) { | 2021 | switch (r_type) { |
| 2043 | .NONE => unreachable, | 2022 | .NONE => unreachable, |
| ... | @@ -2156,18 +2135,6 @@ const riscv = struct { | ... | @@ -2156,18 +2135,6 @@ const riscv = struct { |
| 2156 | 2135 | ||
| 2157 | else => |x| switch (@intFromEnum(x)) { | 2136 | else => |x| switch (@intFromEnum(x)) { |
| 2158 | // Zig custom relocations | 2137 | // Zig custom relocations |
| 2159 | Elf.R_ZIG_GOT_HI20 => { | ||
| 2160 | assert(target.flags.has_zig_got); | ||
| 2161 | const disp: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow); | ||
| 2162 | riscv_util.writeInstU(code[r_offset..][0..4], disp); | ||
| 2163 | }, | ||
| 2164 | |||
| 2165 | Elf.R_ZIG_GOT_LO12 => { | ||
| 2166 | assert(target.flags.has_zig_got); | ||
| 2167 | const value: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow); | ||
| 2168 | riscv_util.writeInstI(code[r_offset..][0..4], value); | ||
| 2169 | }, | ||
| 2170 | |||
| 2171 | Elf.R_GOT_HI20_STATIC => { | 2138 | Elf.R_GOT_HI20_STATIC => { |
| 2172 | assert(target.flags.has_got); | 2139 | assert(target.flags.has_got); |
| 2173 | const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow); | 2140 | const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow); |
src/link/Elf/Symbol.zig-25| ... | @@ -217,25 +217,6 @@ pub fn tlsDescAddress(symbol: Symbol, elf_file: *Elf) i64 { | ... | @@ -217,25 +217,6 @@ pub fn tlsDescAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 217 | return entry.address(elf_file); | 217 | return entry.address(elf_file); |
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | const GetOrCreateZigGotEntryResult = struct { | ||
| 221 | found_existing: bool, | ||
| 222 | index: ZigGotSection.Index, | ||
| 223 | }; | ||
| 224 | |||
| 225 | pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult { | ||
| 226 | assert(!elf_file.base.isRelocatable()); | ||
| 227 | assert(symbol.flags.needs_zig_got); | ||
| 228 | if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).zig_got }; | ||
| 229 | const index = try elf_file.zig_got.addSymbol(symbol_index, elf_file); | ||
| 230 | return .{ .found_existing = false, .index = index }; | ||
| 231 | } | ||
| 232 | |||
| 233 | pub fn zigGotAddress(symbol: Symbol, elf_file: *Elf) i64 { | ||
| 234 | if (!symbol.flags.has_zig_got) return 0; | ||
| 235 | const extras = symbol.extra(elf_file); | ||
| 236 | return elf_file.zig_got.entryAddress(extras.zig_got, elf_file); | ||
| 237 | } | ||
| 238 | |||
| 239 | pub fn zigOffsetTableAddress(symbol: Symbol, elf_file: *Elf) i64 { | 220 | pub fn zigOffsetTableAddress(symbol: Symbol, elf_file: *Elf) i64 { |
| 240 | if (!symbol.flags.zig_offset_table) return 0; | 221 | if (!symbol.flags.zig_offset_table) return 0; |
| 241 | const zo = elf_file.zigObjectPtr().?; | 222 | const zo = elf_file.zigObjectPtr().?; |
| ... | @@ -267,7 +248,6 @@ const AddExtraOpts = struct { | ... | @@ -267,7 +248,6 @@ const AddExtraOpts = struct { |
| 267 | tlsgd: ?u32 = null, | 248 | tlsgd: ?u32 = null, |
| 268 | gottp: ?u32 = null, | 249 | gottp: ?u32 = null, |
| 269 | tlsdesc: ?u32 = null, | 250 | tlsdesc: ?u32 = null, |
| 270 | zig_got: ?u32 = null, | ||
| 271 | zig_offset_table: ?u32 = null, | 251 | zig_offset_table: ?u32 = null, |
| 272 | }; | 252 | }; |
| 273 | 253 | ||
| ... | @@ -465,10 +445,6 @@ pub const Flags = packed struct { | ... | @@ -465,10 +445,6 @@ pub const Flags = packed struct { |
| 465 | needs_tlsdesc: bool = false, | 445 | needs_tlsdesc: bool = false, |
| 466 | has_tlsdesc: bool = false, | 446 | has_tlsdesc: bool = false, |
| 467 | 447 | ||
| 468 | /// Whether the symbol contains .zig.got indirection. | ||
| 469 | needs_zig_got: bool = false, | ||
| 470 | has_zig_got: bool = false, | ||
| 471 | |||
| 472 | /// Whether the symbol is a TLS variable. | 448 | /// Whether the symbol is a TLS variable. |
| 473 | /// TODO this is really not needed if only we operated on esyms between | 449 | /// TODO this is really not needed if only we operated on esyms between |
| 474 | /// codegen and ZigObject. | 450 | /// codegen and ZigObject. |
| ... | @@ -491,7 +467,6 @@ pub const Extra = struct { | ... | @@ -491,7 +467,6 @@ pub const Extra = struct { |
| 491 | tlsgd: u32 = 0, | 467 | tlsgd: u32 = 0, |
| 492 | gottp: u32 = 0, | 468 | gottp: u32 = 0, |
| 493 | tlsdesc: u32 = 0, | 469 | tlsdesc: u32 = 0, |
| 494 | zig_got: u32 = 0, | ||
| 495 | merge_section: u32 = 0, | 470 | merge_section: u32 = 0, |
| 496 | zig_offset_table: u32 = 0, | 471 | zig_offset_table: u32 = 0, |
| 497 | }; | 472 | }; |
src/link/Elf/ZigObject.zig+1-35| ... | @@ -756,15 +756,7 @@ pub fn getOrCreateMetadataForLazySymbol( | ... | @@ -756,15 +756,7 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 756 | .const_data => .{ &gop.value_ptr.rodata_symbol_index, &gop.value_ptr.rodata_state }, | 756 | .const_data => .{ &gop.value_ptr.rodata_symbol_index, &gop.value_ptr.rodata_state }, |
| 757 | }; | 757 | }; |
| 758 | switch (state_ptr.*) { | 758 | switch (state_ptr.*) { |
| 759 | .unused => { | 759 | .unused => symbol_index_ptr.* = try self.newSymbolWithAtom(pt.zcu.gpa, 0), |
| 760 | const gpa = elf_file.base.comp.gpa; | ||
| 761 | const symbol_index = try self.newSymbolWithAtom(gpa, 0); | ||
| 762 | const sym = self.symbol(symbol_index); | ||
| 763 | if (lazy_sym.kind != .code) { | ||
| 764 | sym.flags.needs_zig_got = true; | ||
| 765 | } | ||
| 766 | symbol_index_ptr.* = symbol_index; | ||
| 767 | }, | ||
| 768 | .pending_flush => return symbol_index_ptr.*, | 760 | .pending_flush => return symbol_index_ptr.*, |
| 769 | .flushed => {}, | 761 | .flushed => {}, |
| 770 | } | 762 | } |
| ... | @@ -818,9 +810,6 @@ pub fn getOrCreateMetadataForNav( | ... | @@ -818,9 +810,6 @@ pub fn getOrCreateMetadataForNav( |
| 818 | sym.flags.is_tls = true; | 810 | sym.flags.is_tls = true; |
| 819 | } | 811 | } |
| 820 | } | 812 | } |
| 821 | if (!sym.flags.is_tls and nav_val.typeOf(zcu).zigTypeTag(zcu) != .Fn) { | ||
| 822 | sym.flags.needs_zig_got = true; | ||
| 823 | } | ||
| 824 | gop.value_ptr.* = .{ .symbol_index = symbol_index }; | 813 | gop.value_ptr.* = .{ .symbol_index = symbol_index }; |
| 825 | } | 814 | } |
| 826 | return gop.value_ptr.symbol_index; | 815 | return gop.value_ptr.symbol_index; |
| ... | @@ -921,14 +910,6 @@ fn updateNavCode( | ... | @@ -921,14 +910,6 @@ fn updateNavCode( |
| 921 | sym.value = 0; | 910 | sym.value = 0; |
| 922 | esym.st_value = 0; | 911 | esym.st_value = 0; |
| 923 | 912 | ||
| 924 | if (stt_bits != elf.STT_FUNC) { | ||
| 925 | if (!elf_file.base.isRelocatable()) { | ||
| 926 | log.debug(" (writing new offset table entry)", .{}); | ||
| 927 | assert(sym.flags.has_zig_got); | ||
| 928 | const extra = sym.extra(elf_file); | ||
| 929 | try elf_file.zig_got.writeOne(elf_file, extra.zig_got); | ||
| 930 | } | ||
| 931 | } | ||
| 932 | if (stt_bits == elf.STT_FUNC) { | 913 | if (stt_bits == elf.STT_FUNC) { |
| 933 | const extra = sym.extra(elf_file); | 914 | const extra = sym.extra(elf_file); |
| 934 | const offset_table = self.offsetTablePtr().?; | 915 | const offset_table = self.offsetTablePtr().?; |
| ... | @@ -944,13 +925,6 @@ fn updateNavCode( | ... | @@ -944,13 +925,6 @@ fn updateNavCode( |
| 944 | 925 | ||
| 945 | sym.value = 0; | 926 | sym.value = 0; |
| 946 | esym.st_value = 0; | 927 | esym.st_value = 0; |
| 947 | if (stt_bits != elf.STT_FUNC) { | ||
| 948 | sym.flags.needs_zig_got = true; | ||
| 949 | if (!elf_file.base.isRelocatable()) { | ||
| 950 | const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file); | ||
| 951 | try elf_file.zig_got.writeOne(elf_file, gop.index); | ||
| 952 | } | ||
| 953 | } | ||
| 954 | } | 928 | } |
| 955 | 929 | ||
| 956 | if (elf_file.base.child_pid) |pid| { | 930 | if (elf_file.base.child_pid) |pid| { |
| ... | @@ -1278,16 +1252,8 @@ fn updateLazySymbol( | ... | @@ -1278,16 +1252,8 @@ fn updateLazySymbol( |
| 1278 | errdefer self.freeNavMetadata(elf_file, symbol_index); | 1252 | errdefer self.freeNavMetadata(elf_file, symbol_index); |
| 1279 | 1253 | ||
| 1280 | local_sym.value = 0; | 1254 | local_sym.value = 0; |
| 1281 | if (sym.kind != .code) { | ||
| 1282 | local_sym.flags.needs_zig_got = true; | ||
| 1283 | } | ||
| 1284 | local_esym.st_value = 0; | 1255 | local_esym.st_value = 0; |
| 1285 | 1256 | ||
| 1286 | if (!elf_file.base.isRelocatable()) { | ||
| 1287 | const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file); | ||
| 1288 | try elf_file.zig_got.writeOne(elf_file, gop.index); | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | const shdr = elf_file.shdrs.items[output_section_index]; | 1257 | const shdr = elf_file.shdrs.items[output_section_index]; |
| 1292 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); | 1258 | const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); |
| 1293 | try elf_file.base.file.?.pwriteAll(code, file_offset); | 1259 | try elf_file.base.file.?.pwriteAll(code, file_offset); |
src/link/Elf/relocation.zig-4| ... | @@ -113,10 +113,6 @@ fn formatRelocType( | ... | @@ -113,10 +113,6 @@ fn formatRelocType( |
| 113 | _ = options; | 113 | _ = options; |
| 114 | const r_type = ctx.r_type; | 114 | const r_type = ctx.r_type; |
| 115 | switch (r_type) { | 115 | switch (r_type) { |
| 116 | Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"), | ||
| 117 | Elf.R_ZIG_GOTPCREL => try writer.writeAll("R_ZIG_GOTPCREL"), | ||
| 118 | Elf.R_ZIG_GOT_HI20 => try writer.writeAll("R_ZIG_GOT_HI20"), | ||
| 119 | Elf.R_ZIG_GOT_LO12 => try writer.writeAll("R_ZIG_GOT_LO12"), | ||
| 120 | Elf.R_GOT_HI20_STATIC => try writer.writeAll("R_GOT_HI20_STATIC"), | 116 | Elf.R_GOT_HI20_STATIC => try writer.writeAll("R_GOT_HI20_STATIC"), |
| 121 | Elf.R_GOT_LO12_I_STATIC => try writer.writeAll("R_GOT_LO12_I_STATIC"), | 117 | Elf.R_GOT_LO12_I_STATIC => try writer.writeAll("R_GOT_LO12_I_STATIC"), |
| 122 | else => switch (ctx.cpu_arch) { | 118 | else => switch (ctx.cpu_arch) { |
src/link/Elf/synthetic_sections.zig-209| ... | @@ -223,215 +223,6 @@ pub const DynamicSection = struct { | ... | @@ -223,215 +223,6 @@ pub const DynamicSection = struct { |
| 223 | } | 223 | } |
| 224 | }; | 224 | }; |
| 225 | 225 | ||
| 226 | pub const ZigGotSection = struct { | ||
| 227 | entries: std.ArrayListUnmanaged(Symbol.Index) = .{}, | ||
| 228 | output_symtab_ctx: Elf.SymtabCtx = .{}, | ||
| 229 | flags: Flags = .{}, | ||
| 230 | |||
| 231 | const Flags = packed struct { | ||
| 232 | needs_rela: bool = false, | ||
| 233 | dirty: bool = false, | ||
| 234 | }; | ||
| 235 | |||
| 236 | pub const Index = u32; | ||
| 237 | |||
| 238 | pub fn deinit(zig_got: *ZigGotSection, allocator: Allocator) void { | ||
| 239 | zig_got.entries.deinit(allocator); | ||
| 240 | } | ||
| 241 | |||
| 242 | fn allocateEntry(zig_got: *ZigGotSection, allocator: Allocator) !Index { | ||
| 243 | try zig_got.entries.ensureUnusedCapacity(allocator, 1); | ||
| 244 | // TODO add free list | ||
| 245 | const index = @as(Index, @intCast(zig_got.entries.items.len)); | ||
| 246 | _ = zig_got.entries.addOneAssumeCapacity(); | ||
| 247 | zig_got.flags.dirty = true; | ||
| 248 | return index; | ||
| 249 | } | ||
| 250 | |||
| 251 | pub fn addSymbol(zig_got: *ZigGotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index { | ||
| 252 | const comp = elf_file.base.comp; | ||
| 253 | const gpa = comp.gpa; | ||
| 254 | const zo = elf_file.zigObjectPtr().?; | ||
| 255 | const index = try zig_got.allocateEntry(gpa); | ||
| 256 | const entry = &zig_got.entries.items[index]; | ||
| 257 | entry.* = sym_index; | ||
| 258 | const symbol = zo.symbol(sym_index); | ||
| 259 | symbol.flags.has_zig_got = true; | ||
| 260 | if (elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) { | ||
| 261 | zig_got.flags.needs_rela = true; | ||
| 262 | } | ||
| 263 | symbol.addExtra(.{ .zig_got = index }, elf_file); | ||
| 264 | return index; | ||
| 265 | } | ||
| 266 | |||
| 267 | pub fn entryOffset(zig_got: ZigGotSection, index: Index, elf_file: *Elf) u64 { | ||
| 268 | _ = zig_got; | ||
| 269 | const entry_size = elf_file.archPtrWidthBytes(); | ||
| 270 | const shdr = elf_file.shdrs.items[elf_file.zig_got_section_index.?]; | ||
| 271 | return shdr.sh_offset + @as(u64, entry_size) * index; | ||
| 272 | } | ||
| 273 | |||
| 274 | pub fn entryAddress(zig_got: ZigGotSection, index: Index, elf_file: *Elf) i64 { | ||
| 275 | _ = zig_got; | ||
| 276 | const entry_size = elf_file.archPtrWidthBytes(); | ||
| 277 | const shdr = elf_file.shdrs.items[elf_file.zig_got_section_index.?]; | ||
| 278 | return @as(i64, @intCast(shdr.sh_addr)) + entry_size * index; | ||
| 279 | } | ||
| 280 | |||
| 281 | pub fn size(zig_got: ZigGotSection, elf_file: *Elf) usize { | ||
| 282 | return elf_file.archPtrWidthBytes() * zig_got.entries.items.len; | ||
| 283 | } | ||
| 284 | |||
| 285 | pub fn writeOne(zig_got: *ZigGotSection, elf_file: *Elf, index: Index) !void { | ||
| 286 | const zo = elf_file.zigObjectPtr().?; | ||
| 287 | if (zig_got.flags.dirty) { | ||
| 288 | const needed_size = zig_got.size(elf_file); | ||
| 289 | try elf_file.growAllocSection(elf_file.zig_got_section_index.?, needed_size); | ||
| 290 | zig_got.flags.dirty = false; | ||
| 291 | } | ||
| 292 | const entry_size: u16 = elf_file.archPtrWidthBytes(); | ||
| 293 | const target = elf_file.getTarget(); | ||
| 294 | const endian = target.cpu.arch.endian(); | ||
| 295 | const off = zig_got.entryOffset(index, elf_file); | ||
| 296 | const vaddr: u64 = @intCast(zig_got.entryAddress(index, elf_file)); | ||
| 297 | const entry = zig_got.entries.items[index]; | ||
| 298 | const value = zo.symbol(entry).address(.{}, elf_file); | ||
| 299 | switch (entry_size) { | ||
| 300 | 2 => { | ||
| 301 | var buf: [2]u8 = undefined; | ||
| 302 | std.mem.writeInt(u16, &buf, @intCast(value), endian); | ||
| 303 | try elf_file.base.file.?.pwriteAll(&buf, off); | ||
| 304 | }, | ||
| 305 | 4 => { | ||
| 306 | var buf: [4]u8 = undefined; | ||
| 307 | std.mem.writeInt(u32, &buf, @intCast(value), endian); | ||
| 308 | try elf_file.base.file.?.pwriteAll(&buf, off); | ||
| 309 | }, | ||
| 310 | 8 => { | ||
| 311 | var buf: [8]u8 = undefined; | ||
| 312 | std.mem.writeInt(u64, &buf, @intCast(value), endian); | ||
| 313 | try elf_file.base.file.?.pwriteAll(&buf, off); | ||
| 314 | |||
| 315 | if (elf_file.base.child_pid) |pid| { | ||
| 316 | switch (builtin.os.tag) { | ||
| 317 | .linux => { | ||
| 318 | var local_vec: [1]std.posix.iovec_const = .{.{ | ||
| 319 | .base = &buf, | ||
| 320 | .len = buf.len, | ||
| 321 | }}; | ||
| 322 | var remote_vec: [1]std.posix.iovec_const = .{.{ | ||
| 323 | .base = @as([*]u8, @ptrFromInt(@as(usize, @intCast(vaddr)))), | ||
| 324 | .len = buf.len, | ||
| 325 | }}; | ||
| 326 | const rc = std.os.linux.process_vm_writev(pid, &local_vec, &remote_vec, 0); | ||
| 327 | switch (std.os.linux.E.init(rc)) { | ||
| 328 | .SUCCESS => assert(rc == buf.len), | ||
| 329 | else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}), | ||
| 330 | } | ||
| 331 | }, | ||
| 332 | else => return error.HotSwapUnavailableOnHostOperatingSystem, | ||
| 333 | } | ||
| 334 | } | ||
| 335 | }, | ||
| 336 | else => unreachable, | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 340 | pub fn writeAll(zig_got: ZigGotSection, elf_file: *Elf, writer: anytype) !void { | ||
| 341 | const zo = elf_file.zigObjectPtr().?; | ||
| 342 | for (zig_got.entries.items) |entry| { | ||
| 343 | const symbol = zo.symbol(entry); | ||
| 344 | const value = symbol.address(.{ .plt = false }, elf_file); | ||
| 345 | try writeInt(value, elf_file, writer); | ||
| 346 | } | ||
| 347 | } | ||
| 348 | |||
| 349 | pub fn numRela(zig_got: ZigGotSection) usize { | ||
| 350 | return zig_got.entries.items.len; | ||
| 351 | } | ||
| 352 | |||
| 353 | pub fn addRela(zig_got: ZigGotSection, elf_file: *Elf) !void { | ||
| 354 | const comp = elf_file.base.comp; | ||
| 355 | const gpa = comp.gpa; | ||
| 356 | const cpu_arch = elf_file.getTarget().cpu.arch; | ||
| 357 | const zo = elf_file.zigObjectPtr().?; | ||
| 358 | try elf_file.rela_dyn.ensureUnusedCapacity(gpa, zig_got.numRela()); | ||
| 359 | for (zig_got.entries.items) |entry| { | ||
| 360 | const symbol = zo.symbol(entry); | ||
| 361 | const offset = symbol.zigGotAddress(elf_file); | ||
| 362 | elf_file.addRelaDynAssumeCapacity(.{ | ||
| 363 | .offset = @intCast(offset), | ||
| 364 | .type = relocation.encode(.rel, cpu_arch), | ||
| 365 | .addend = symbol.address(.{ .plt = false }, elf_file), | ||
| 366 | }); | ||
| 367 | } | ||
| 368 | } | ||
| 369 | |||
| 370 | pub fn updateSymtabSize(zig_got: *ZigGotSection, elf_file: *Elf) void { | ||
| 371 | const zo = elf_file.zigObjectPtr().?; | ||
| 372 | zig_got.output_symtab_ctx.nlocals = @as(u32, @intCast(zig_got.entries.items.len)); | ||
| 373 | for (zig_got.entries.items) |entry| { | ||
| 374 | const name = zo.symbol(entry).name(elf_file); | ||
| 375 | zig_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$ziggot".len)) + 1; | ||
| 376 | } | ||
| 377 | } | ||
| 378 | |||
| 379 | pub fn writeSymtab(zig_got: ZigGotSection, elf_file: *Elf) void { | ||
| 380 | const zo = elf_file.zigObjectPtr().?; | ||
| 381 | for (zig_got.entries.items, zig_got.output_symtab_ctx.ilocal.., 0..) |entry, ilocal, index| { | ||
| 382 | const symbol = zo.symbol(entry); | ||
| 383 | const symbol_name = symbol.name(elf_file); | ||
| 384 | const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); | ||
| 385 | elf_file.strtab.appendSliceAssumeCapacity(symbol_name); | ||
| 386 | elf_file.strtab.appendSliceAssumeCapacity("$ziggot"); | ||
| 387 | elf_file.strtab.appendAssumeCapacity(0); | ||
| 388 | const st_value = zig_got.entryAddress(@intCast(index), elf_file); | ||
| 389 | const st_size = elf_file.archPtrWidthBytes(); | ||
| 390 | elf_file.symtab.items[ilocal] = .{ | ||
| 391 | .st_name = st_name, | ||
| 392 | .st_info = elf.STT_OBJECT, | ||
| 393 | .st_other = 0, | ||
| 394 | .st_shndx = @intCast(elf_file.zig_got_section_index.?), | ||
| 395 | .st_value = @intCast(st_value), | ||
| 396 | .st_size = st_size, | ||
| 397 | }; | ||
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 401 | const FormatCtx = struct { | ||
| 402 | zig_got: ZigGotSection, | ||
| 403 | elf_file: *Elf, | ||
| 404 | }; | ||
| 405 | |||
| 406 | pub fn fmt(zig_got: ZigGotSection, elf_file: *Elf) std.fmt.Formatter(format2) { | ||
| 407 | return .{ .data = .{ .zig_got = zig_got, .elf_file = elf_file } }; | ||
| 408 | } | ||
| 409 | |||
| 410 | pub fn format2( | ||
| 411 | ctx: FormatCtx, | ||
| 412 | comptime unused_fmt_string: []const u8, | ||
| 413 | options: std.fmt.FormatOptions, | ||
| 414 | writer: anytype, | ||
| 415 | ) !void { | ||
| 416 | _ = options; | ||
| 417 | _ = unused_fmt_string; | ||
| 418 | const zig_got = ctx.zig_got; | ||
| 419 | const elf_file = ctx.elf_file; | ||
| 420 | try writer.writeAll(".zig.got\n"); | ||
| 421 | for (zig_got.entries.items, 0..) |entry, index| { | ||
| 422 | const zo = elf_file.zigObjectPtr().?; | ||
| 423 | const symbol = zo.symbol(entry); | ||
| 424 | try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{ | ||
| 425 | index, | ||
| 426 | zig_got.entryAddress(@intCast(index), elf_file), | ||
| 427 | entry, | ||
| 428 | symbol.address(.{}, elf_file), | ||
| 429 | symbol.name(elf_file), | ||
| 430 | }); | ||
| 431 | } | ||
| 432 | } | ||
| 433 | }; | ||
| 434 | |||
| 435 | pub const GotSection = struct { | 226 | pub const GotSection = struct { |
| 436 | entries: std.ArrayListUnmanaged(Entry) = .{}, | 227 | entries: std.ArrayListUnmanaged(Entry) = .{}, |
| 437 | output_symtab_ctx: Elf.SymtabCtx = .{}, | 228 | output_symtab_ctx: Elf.SymtabCtx = .{}, |