| author | |
| committer | |
| log | 137d43c0ea77d5cc21040eadbd38fdfd945a3216 |
| tree | d0317c251f8fbd503e8c35d441123200fb16b186 |
| parent | 26da7c8207ff73927bcc8d5608703175074e266f |
5 files changed, 92 insertions(+), 116 deletions(-)
src/link/Elf.zig+13-6| ... | @@ -2060,6 +2060,9 @@ fn scanRelocs(self: *Elf) !void { | ... | @@ -2060,6 +2060,9 @@ fn scanRelocs(self: *Elf) !void { |
| 2060 | for (self.objects.items) |index| { | 2060 | for (self.objects.items) |index| { |
| 2061 | try self.file(index).?.createSymbolIndirection(self); | 2061 | try self.file(index).?.createSymbolIndirection(self); |
| 2062 | } | 2062 | } |
| 2063 | for (self.shared_objects.items) |index| { | ||
| 2064 | try self.file(index).?.createSymbolIndirection(self); | ||
| 2065 | } | ||
| 2063 | if (self.got.flags.needs_tlsld) { | 2066 | if (self.got.flags.needs_tlsld) { |
| 2064 | log.debug("program needs TLSLD", .{}); | 2067 | log.debug("program needs TLSLD", .{}); |
| 2065 | try self.got.addTlsLdSymbol(self); | 2068 | try self.got.addTlsLdSymbol(self); |
| ... | @@ -4431,11 +4434,13 @@ pub fn updateSymtabSize(self: *Elf) !void { | ... | @@ -4431,11 +4434,13 @@ pub fn updateSymtabSize(self: *Elf) !void { |
| 4431 | strsize += ctx.strsize; | 4434 | strsize += ctx.strsize; |
| 4432 | } | 4435 | } |
| 4433 | 4436 | ||
| 4434 | if (self.zig_got_section_index) |_| { | 4437 | if (self.zigObjectPtr()) |_| { |
| 4435 | self.zig_got.output_symtab_ctx.ilocal = nlocals + 1; | 4438 | if (self.zig_got_section_index) |_| { |
| 4436 | self.zig_got.updateSymtabSize(self); | 4439 | self.zig_got.output_symtab_ctx.ilocal = nlocals + 1; |
| 4437 | nlocals += self.zig_got.output_symtab_ctx.nlocals; | 4440 | self.zig_got.updateSymtabSize(self); |
| 4438 | strsize += self.zig_got.output_symtab_ctx.strsize; | 4441 | nlocals += self.zig_got.output_symtab_ctx.nlocals; |
| 4442 | strsize += self.zig_got.output_symtab_ctx.strsize; | ||
| 4443 | } | ||
| 4439 | } | 4444 | } |
| 4440 | 4445 | ||
| 4441 | if (self.got_section_index) |_| { | 4446 | if (self.got_section_index) |_| { |
| ... | @@ -4574,7 +4579,9 @@ fn writeSyntheticSections(self: *Elf) !void { | ... | @@ -4574,7 +4579,9 @@ fn writeSyntheticSections(self: *Elf) !void { |
| 4574 | const shdr = self.shdrs.items[shndx]; | 4579 | const shdr = self.shdrs.items[shndx]; |
| 4575 | try self.got.addRela(self); | 4580 | try self.got.addRela(self); |
| 4576 | try self.copy_rel.addRela(self); | 4581 | try self.copy_rel.addRela(self); |
| 4577 | try self.zig_got.addRela(self); | 4582 | if (self.zigObjectPtr()) |_| { |
| 4583 | try self.zig_got.addRela(self); | ||
| 4584 | } | ||
| 4578 | self.sortRelaDyn(); | 4585 | self.sortRelaDyn(); |
| 4579 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset); | 4586 | try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset); |
| 4580 | } | 4587 | } |
src/link/Elf/Object.zig-45| ... | @@ -561,51 +561,6 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void { | ... | @@ -561,51 +561,6 @@ pub fn scanRelocs(self: *Object, elf_file: *Elf, undefs: anytype) !void { |
| 561 | } | 561 | } |
| 562 | } | 562 | } |
| 563 | 563 | ||
| 564 | pub fn createSymbolIndirection(self: *Object, elf_file: *Elf) !void { | ||
| 565 | for (self.symbols.items, 0..) |*sym, i| { | ||
| 566 | const ref = self.resolveSymbol(@intCast(i), elf_file); | ||
| 567 | const ref_sym = elf_file.symbol(ref) orelse continue; | ||
| 568 | if (ref_sym.file(elf_file).?.index() != self.index) continue; | ||
| 569 | if (!sym.isLocal(elf_file) and !sym.flags.has_dynamic) { | ||
| 570 | log.debug("'{s}' is non-local", .{sym.name(elf_file)}); | ||
| 571 | try elf_file.dynsym.addSymbol(ref, elf_file); | ||
| 572 | } | ||
| 573 | if (sym.flags.needs_got) { | ||
| 574 | log.debug("'{s}' needs GOT", .{sym.name(elf_file)}); | ||
| 575 | _ = try elf_file.got.addGotSymbol(ref, elf_file); | ||
| 576 | } | ||
| 577 | if (sym.flags.needs_plt) { | ||
| 578 | if (sym.flags.is_canonical) { | ||
| 579 | log.debug("'{s}' needs CPLT", .{sym.name(elf_file)}); | ||
| 580 | sym.flags.@"export" = true; | ||
| 581 | try elf_file.plt.addSymbol(ref, elf_file); | ||
| 582 | } else if (sym.flags.needs_got) { | ||
| 583 | log.debug("'{s}' needs PLTGOT", .{sym.name(elf_file)}); | ||
| 584 | try elf_file.plt_got.addSymbol(ref, elf_file); | ||
| 585 | } else { | ||
| 586 | log.debug("'{s}' needs PLT", .{sym.name(elf_file)}); | ||
| 587 | try elf_file.plt.addSymbol(ref, elf_file); | ||
| 588 | } | ||
| 589 | } | ||
| 590 | if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) { | ||
| 591 | log.debug("'{s}' needs COPYREL", .{sym.name(elf_file)}); | ||
| 592 | try elf_file.copy_rel.addSymbol(ref, elf_file); | ||
| 593 | } | ||
| 594 | if (sym.flags.needs_tlsgd) { | ||
| 595 | log.debug("'{s}' needs TLSGD", .{sym.name(elf_file)}); | ||
| 596 | try elf_file.got.addTlsGdSymbol(ref, elf_file); | ||
| 597 | } | ||
| 598 | if (sym.flags.needs_gottp) { | ||
| 599 | log.debug("'{s}' needs GOTTP", .{sym.name(elf_file)}); | ||
| 600 | try elf_file.got.addGotTpSymbol(ref, elf_file); | ||
| 601 | } | ||
| 602 | if (sym.flags.needs_tlsdesc) { | ||
| 603 | log.debug("'{s}' needs TLSDESC", .{sym.name(elf_file)}); | ||
| 604 | try elf_file.got.addTlsDescSymbol(ref, elf_file); | ||
| 605 | } | ||
| 606 | } | ||
| 607 | } | ||
| 608 | |||
| 609 | pub fn resolveSymbols(self: *Object, elf_file: *Elf) !void { | 564 | pub fn resolveSymbols(self: *Object, elf_file: *Elf) !void { |
| 610 | const gpa = elf_file.base.comp.gpa; | 565 | const gpa = elf_file.base.comp.gpa; |
| 611 | 566 |
src/link/Elf/SharedObject.zig+10-3| ... | @@ -219,9 +219,7 @@ fn initSymbols(self: *SharedObject, elf_file: *Elf, opts: struct { | ... | @@ -219,9 +219,7 @@ fn initSymbols(self: *SharedObject, elf_file: *Elf, opts: struct { |
| 219 | self.versionString(self.versyms.items[i]), | 219 | self.versionString(self.versyms.items[i]), |
| 220 | }); | 220 | }); |
| 221 | defer gpa.free(mangled); | 221 | defer gpa.free(mangled); |
| 222 | const name_off = @as(u32, @intCast(self.strtab.items.len)); | 222 | break :blk try self.addString(gpa, mangled); |
| 223 | try self.strtab.writer(gpa).print("{s}\x00", .{mangled}); | ||
| 224 | break :blk name_off; | ||
| 225 | } else sym.st_name; | 223 | } else sym.st_name; |
| 226 | const out_esym_index: u32 = @intCast(self.symtab.items.len); | 224 | const out_esym_index: u32 = @intCast(self.symtab.items.len); |
| 227 | const out_esym = self.symtab.addOneAssumeCapacity(); | 225 | const out_esym = self.symtab.addOneAssumeCapacity(); |
| ... | @@ -230,6 +228,7 @@ fn initSymbols(self: *SharedObject, elf_file: *Elf, opts: struct { | ... | @@ -230,6 +228,7 @@ fn initSymbols(self: *SharedObject, elf_file: *Elf, opts: struct { |
| 230 | const out_sym_index = self.addSymbolAssumeCapacity(); | 228 | const out_sym_index = self.addSymbolAssumeCapacity(); |
| 231 | const out_sym = &self.symbols.items[out_sym_index]; | 229 | const out_sym = &self.symbols.items[out_sym_index]; |
| 232 | out_sym.value = @intCast(out_esym.st_value); | 230 | out_sym.value = @intCast(out_esym.st_value); |
| 231 | out_sym.name_offset = name_off; | ||
| 233 | out_sym.ref = .{ .index = 0, .file = 0 }; | 232 | out_sym.ref = .{ .index = 0, .file = 0 }; |
| 234 | out_sym.esym_index = out_esym_index; | 233 | out_sym.esym_index = out_esym_index; |
| 235 | out_sym.version_index = self.versyms.items[out_esym_index]; | 234 | out_sym.version_index = self.versyms.items[out_esym_index]; |
| ... | @@ -394,6 +393,14 @@ pub fn symbolAliases(self: *SharedObject, index: u32, elf_file: *Elf) []const u3 | ... | @@ -394,6 +393,14 @@ pub fn symbolAliases(self: *SharedObject, index: u32, elf_file: *Elf) []const u3 |
| 394 | return aliases.items[start..end]; | 393 | return aliases.items[start..end]; |
| 395 | } | 394 | } |
| 396 | 395 | ||
| 396 | fn addString(self: *SharedObject, allocator: Allocator, str: []const u8) !u32 { | ||
| 397 | const off: u32 = @intCast(self.strtab.items.len); | ||
| 398 | try self.strtab.ensureUnusedCapacity(allocator, str.len + 1); | ||
| 399 | self.strtab.appendSliceAssumeCapacity(str); | ||
| 400 | self.strtab.appendAssumeCapacity(0); | ||
| 401 | return off; | ||
| 402 | } | ||
| 403 | |||
| 397 | pub fn getString(self: SharedObject, off: u32) [:0]const u8 { | 404 | pub fn getString(self: SharedObject, off: u32) [:0]const u8 { |
| 398 | assert(off < self.strtab.items.len); | 405 | assert(off < self.strtab.items.len); |
| 399 | return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + off)), 0); | 406 | return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.items.ptr + off)), 0); |
src/link/Elf/ZigObject.zig-58| ... | @@ -442,64 +442,6 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void { | ... | @@ -442,64 +442,6 @@ pub fn scanRelocs(self: *ZigObject, elf_file: *Elf, undefs: anytype) !void { |
| 442 | } | 442 | } |
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | pub fn createSymbolIndirection(self: *ZigObject, elf_file: *Elf) !void { | ||
| 446 | const impl = struct { | ||
| 447 | fn impl(sym: *Symbol, ref: Elf.Ref, ef: *Elf) !void { | ||
| 448 | if (!sym.isLocal(ef) and !sym.flags.has_dynamic) { | ||
| 449 | log.debug("'{s}' is non-local", .{sym.name(ef)}); | ||
| 450 | try ef.dynsym.addSymbol(ref, ef); | ||
| 451 | } | ||
| 452 | if (sym.flags.needs_got) { | ||
| 453 | log.debug("'{s}' needs GOT", .{sym.name(ef)}); | ||
| 454 | _ = try ef.got.addGotSymbol(ref, ef); | ||
| 455 | } | ||
| 456 | if (sym.flags.needs_plt) { | ||
| 457 | if (sym.flags.is_canonical) { | ||
| 458 | log.debug("'{s}' needs CPLT", .{sym.name(ef)}); | ||
| 459 | sym.flags.@"export" = true; | ||
| 460 | try ef.plt.addSymbol(ref, ef); | ||
| 461 | } else if (sym.flags.needs_got) { | ||
| 462 | log.debug("'{s}' needs PLTGOT", .{sym.name(ef)}); | ||
| 463 | try ef.plt_got.addSymbol(ref, ef); | ||
| 464 | } else { | ||
| 465 | log.debug("'{s}' needs PLT", .{sym.name(ef)}); | ||
| 466 | try ef.plt.addSymbol(ref, ef); | ||
| 467 | } | ||
| 468 | } | ||
| 469 | if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) { | ||
| 470 | log.debug("'{s}' needs COPYREL", .{sym.name(ef)}); | ||
| 471 | try ef.copy_rel.addSymbol(ref, ef); | ||
| 472 | } | ||
| 473 | if (sym.flags.needs_tlsgd) { | ||
| 474 | log.debug("'{s}' needs TLSGD", .{sym.name(ef)}); | ||
| 475 | try ef.got.addTlsGdSymbol(ref, ef); | ||
| 476 | } | ||
| 477 | if (sym.flags.needs_gottp) { | ||
| 478 | log.debug("'{s}' needs GOTTP", .{sym.name(ef)}); | ||
| 479 | try ef.got.addGotTpSymbol(ref, ef); | ||
| 480 | } | ||
| 481 | if (sym.flags.needs_tlsdesc) { | ||
| 482 | log.debug("'{s}' needs TLSDESC", .{sym.name(ef)}); | ||
| 483 | try ef.got.addTlsDescSymbol(ref, ef); | ||
| 484 | } | ||
| 485 | } | ||
| 486 | }.impl; | ||
| 487 | for (self.local_symbols.items, 0..) |index, i| { | ||
| 488 | const sym = &self.symbols.items[index]; | ||
| 489 | const ref = self.resolveSymbol(@intCast(i), elf_file); | ||
| 490 | const ref_sym = elf_file.symbol(ref) orelse continue; | ||
| 491 | if (ref_sym.file(elf_file).?.index() != self.index) continue; | ||
| 492 | try impl(sym, ref, elf_file); | ||
| 493 | } | ||
| 494 | for (self.global_symbols.items, 0..) |index, i| { | ||
| 495 | const sym = &self.symbols.items[index]; | ||
| 496 | const ref = self.resolveSymbol(@intCast(i | global_symbol_bit), elf_file); | ||
| 497 | const ref_sym = elf_file.symbol(ref) orelse continue; | ||
| 498 | if (ref_sym.file(elf_file).?.index() != self.index) continue; | ||
| 499 | try impl(sym, ref, elf_file); | ||
| 500 | } | ||
| 501 | } | ||
| 502 | |||
| 503 | pub fn markLive(self: *ZigObject, elf_file: *Elf) void { | 445 | pub fn markLive(self: *ZigObject, elf_file: *Elf) void { |
| 504 | for (self.global_symbols.items, 0..) |index, i| { | 446 | for (self.global_symbols.items, 0..) |index, i| { |
| 505 | const global = self.symbols.items[index]; | 447 | const global = self.symbols.items[index]; |
src/link/Elf/file.zig+69-4| ... | @@ -101,10 +101,74 @@ pub const File = union(enum) { | ... | @@ -101,10 +101,74 @@ pub const File = union(enum) { |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | pub fn createSymbolIndirection(file: File, elf_file: *Elf) !void { | 103 | pub fn createSymbolIndirection(file: File, elf_file: *Elf) !void { |
| 104 | return switch (file) { | 104 | const impl = struct { |
| 105 | .linker_defined, .shared_object => unreachable, | 105 | fn impl(sym: *Symbol, ref: Elf.Ref, ef: *Elf) !void { |
| 106 | inline else => |x| x.createSymbolIndirection(elf_file), | 106 | if (!sym.isLocal(ef) and !sym.flags.has_dynamic) { |
| 107 | }; | 107 | log.debug("'{s}' is non-local", .{sym.name(ef)}); |
| 108 | try ef.dynsym.addSymbol(ref, ef); | ||
| 109 | } | ||
| 110 | if (sym.flags.needs_got) { | ||
| 111 | log.debug("'{s}' needs GOT", .{sym.name(ef)}); | ||
| 112 | _ = try ef.got.addGotSymbol(ref, ef); | ||
| 113 | } | ||
| 114 | if (sym.flags.needs_plt) { | ||
| 115 | if (sym.flags.is_canonical) { | ||
| 116 | log.debug("'{s}' needs CPLT", .{sym.name(ef)}); | ||
| 117 | sym.flags.@"export" = true; | ||
| 118 | try ef.plt.addSymbol(ref, ef); | ||
| 119 | } else if (sym.flags.needs_got) { | ||
| 120 | log.debug("'{s}' needs PLTGOT", .{sym.name(ef)}); | ||
| 121 | try ef.plt_got.addSymbol(ref, ef); | ||
| 122 | } else { | ||
| 123 | log.debug("'{s}' needs PLT", .{sym.name(ef)}); | ||
| 124 | try ef.plt.addSymbol(ref, ef); | ||
| 125 | } | ||
| 126 | } | ||
| 127 | if (sym.flags.needs_copy_rel and !sym.flags.has_copy_rel) { | ||
| 128 | log.debug("'{s}' needs COPYREL", .{sym.name(ef)}); | ||
| 129 | try ef.copy_rel.addSymbol(ref, ef); | ||
| 130 | } | ||
| 131 | if (sym.flags.needs_tlsgd) { | ||
| 132 | log.debug("'{s}' needs TLSGD", .{sym.name(ef)}); | ||
| 133 | try ef.got.addTlsGdSymbol(ref, ef); | ||
| 134 | } | ||
| 135 | if (sym.flags.needs_gottp) { | ||
| 136 | log.debug("'{s}' needs GOTTP", .{sym.name(ef)}); | ||
| 137 | try ef.got.addGotTpSymbol(ref, ef); | ||
| 138 | } | ||
| 139 | if (sym.flags.needs_tlsdesc) { | ||
| 140 | log.debug("'{s}' needs TLSDESC", .{sym.name(ef)}); | ||
| 141 | try ef.got.addTlsDescSymbol(ref, ef); | ||
| 142 | } | ||
| 143 | } | ||
| 144 | }.impl; | ||
| 145 | |||
| 146 | switch (file) { | ||
| 147 | .zig_object => |x| { | ||
| 148 | for (x.local_symbols.items, 0..) |idx, i| { | ||
| 149 | const sym = &x.symbols.items[idx]; | ||
| 150 | const ref = x.resolveSymbol(@intCast(i), elf_file); | ||
| 151 | const ref_sym = elf_file.symbol(ref) orelse continue; | ||
| 152 | if (ref_sym.file(elf_file).?.index() != x.index) continue; | ||
| 153 | try impl(sym, ref, elf_file); | ||
| 154 | } | ||
| 155 | for (x.global_symbols.items, 0..) |idx, i| { | ||
| 156 | const sym = &x.symbols.items[idx]; | ||
| 157 | const ref = x.resolveSymbol(@intCast(i | ZigObject.global_symbol_bit), elf_file); | ||
| 158 | const ref_sym = elf_file.symbol(ref) orelse continue; | ||
| 159 | if (ref_sym.file(elf_file).?.index() != x.index) continue; | ||
| 160 | try impl(sym, ref, elf_file); | ||
| 161 | } | ||
| 162 | }, | ||
| 163 | inline else => |x| { | ||
| 164 | for (x.symbols.items, 0..) |*sym, i| { | ||
| 165 | const ref = x.resolveSymbol(@intCast(i), elf_file); | ||
| 166 | const ref_sym = elf_file.symbol(ref) orelse continue; | ||
| 167 | if (ref_sym.file(elf_file).?.index() != x.index) continue; | ||
| 168 | try impl(sym, ref, elf_file); | ||
| 169 | } | ||
| 170 | }, | ||
| 171 | } | ||
| 108 | } | 172 | } |
| 109 | 173 | ||
| 110 | pub fn atom(file: File, atom_index: Atom.Index) ?*Atom { | 174 | pub fn atom(file: File, atom_index: Atom.Index) ?*Atom { |
| ... | @@ -239,6 +303,7 @@ pub const File = union(enum) { | ... | @@ -239,6 +303,7 @@ pub const File = union(enum) { |
| 239 | 303 | ||
| 240 | const std = @import("std"); | 304 | const std = @import("std"); |
| 241 | const elf = std.elf; | 305 | const elf = std.elf; |
| 306 | const log = std.log.scoped(.link); | ||
| 242 | 307 | ||
| 243 | const Allocator = std.mem.Allocator; | 308 | const Allocator = std.mem.Allocator; |
| 244 | const Archive = @import("Archive.zig"); | 309 | const Archive = @import("Archive.zig"); |