| author | |
| committer | |
| log | dbe13200f1b5a20367b9e5ec288a8ec27fa2d505 |
| tree | 3cb3e4f6b460bb2616134a3f577d30374cc0a3f8 |
| parent | 8055f687659de87ce0101cb3e459699b4541a8b7 |
4 files changed, 54 insertions(+), 21 deletions(-)
src/link/Elf.zig+8-8| ... | @@ -494,6 +494,7 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -494,6 +494,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 494 | const ptr_size = self.ptrWidthBytes(); | 494 | const ptr_size = self.ptrWidthBytes(); |
| 495 | const ptr_bit_width = self.base.options.target.ptrBitWidth(); | 495 | const ptr_bit_width = self.base.options.target.ptrBitWidth(); |
| 496 | const is_linux = self.base.options.target.os.tag == .linux; | 496 | const is_linux = self.base.options.target.os.tag == .linux; |
| 497 | const zig_object = self.zigObjectPtr().?; | ||
| 497 | 498 | ||
| 498 | const fillSection = struct { | 499 | const fillSection = struct { |
| 499 | fn fillSection(elf_file: *Elf, shdr: *elf.Elf64_Shdr, size: u64, phndx: ?u16) void { | 500 | fn fillSection(elf_file: *Elf, shdr: *elf.Elf64_Shdr, size: u64, phndx: ?u16) void { |
| ... | @@ -597,6 +598,7 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -597,6 +598,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 597 | const shdr = &self.shdrs.items[self.zig_text_section_index.?]; | 598 | const shdr = &self.shdrs.items[self.zig_text_section_index.?]; |
| 598 | fillSection(self, shdr, self.base.options.program_code_size_hint, self.phdr_zig_load_re_index); | 599 | fillSection(self, shdr, self.base.options.program_code_size_hint, self.phdr_zig_load_re_index); |
| 599 | if (self.isObject()) { | 600 | if (self.isObject()) { |
| 601 | try zig_object.addSectionSymbol(self.zig_text_section_index.?, self); | ||
| 600 | self.zig_text_rela_section_index = try self.addRelaShdr( | 602 | self.zig_text_rela_section_index = try self.addRelaShdr( |
| 601 | ".rela.text.zig", | 603 | ".rela.text.zig", |
| 602 | self.zig_text_section_index.?, | 604 | self.zig_text_section_index.?, |
| ... | @@ -643,6 +645,7 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -643,6 +645,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 643 | const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?]; | 645 | const shdr = &self.shdrs.items[self.zig_data_rel_ro_section_index.?]; |
| 644 | fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index); | 646 | fillSection(self, shdr, 1024, self.phdr_zig_load_ro_index); |
| 645 | if (self.isObject()) { | 647 | if (self.isObject()) { |
| 648 | try zig_object.addSectionSymbol(self.zig_data_rel_ro_section_index.?, self); | ||
| 646 | self.zig_data_rel_ro_rela_section_index = try self.addRelaShdr( | 649 | self.zig_data_rel_ro_rela_section_index = try self.addRelaShdr( |
| 647 | ".rela.data.rel.ro.zig", | 650 | ".rela.data.rel.ro.zig", |
| 648 | self.zig_data_rel_ro_section_index.?, | 651 | self.zig_data_rel_ro_section_index.?, |
| ... | @@ -668,6 +671,7 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -668,6 +671,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 668 | const shdr = &self.shdrs.items[self.zig_data_section_index.?]; | 671 | const shdr = &self.shdrs.items[self.zig_data_section_index.?]; |
| 669 | fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index); | 672 | fillSection(self, shdr, 1024, self.phdr_zig_load_rw_index); |
| 670 | if (self.isObject()) { | 673 | if (self.isObject()) { |
| 674 | try zig_object.addSectionSymbol(self.zig_data_section_index.?, self); | ||
| 671 | self.zig_data_rela_section_index = try self.addRelaShdr( | 675 | self.zig_data_rela_section_index = try self.addRelaShdr( |
| 672 | ".rela.data.zig", | 676 | ".rela.data.zig", |
| 673 | self.zig_data_section_index.?, | 677 | self.zig_data_section_index.?, |
| ... | @@ -697,12 +701,12 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -697,12 +701,12 @@ pub fn initMetadata(self: *Elf) !void { |
| 697 | shdr.sh_size = phdr.p_memsz; | 701 | shdr.sh_size = phdr.p_memsz; |
| 698 | try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_bss_section_index.?, phndx); | 702 | try self.phdr_to_shdr_table.putNoClobber(gpa, self.zig_bss_section_index.?, phndx); |
| 699 | } else { | 703 | } else { |
| 704 | try zig_object.addSectionSymbol(self.zig_bss_section_index.?, self); | ||
| 700 | shdr.sh_size = 1024; | 705 | shdr.sh_size = 1024; |
| 701 | } | 706 | } |
| 702 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{}); | 707 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{}); |
| 703 | } | 708 | } |
| 704 | 709 | ||
| 705 | const zig_object = self.zigObjectPtr().?; | ||
| 706 | if (zig_object.dwarf) |*dw| { | 710 | if (zig_object.dwarf) |*dw| { |
| 707 | if (self.debug_str_section_index == null) { | 711 | if (self.debug_str_section_index == null) { |
| 708 | assert(dw.strtab.buffer.items.len == 0); | 712 | assert(dw.strtab.buffer.items.len == 0); |
| ... | @@ -3801,23 +3805,19 @@ fn sortShdrs(self: *Elf) !void { | ... | @@ -3801,23 +3805,19 @@ fn sortShdrs(self: *Elf) !void { |
| 3801 | if (self.zigObjectPtr()) |zig_object| { | 3805 | if (self.zigObjectPtr()) |zig_object| { |
| 3802 | for (zig_object.atoms.items) |atom_index| { | 3806 | for (zig_object.atoms.items) |atom_index| { |
| 3803 | const atom_ptr = self.atom(atom_index) orelse continue; | 3807 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 3804 | if (!atom_ptr.flags.alive) continue; | 3808 | atom_ptr.output_section_index = backlinks[atom_ptr.output_section_index]; |
| 3805 | const out_shndx = atom_ptr.outputShndx() orelse continue; | ||
| 3806 | atom_ptr.output_section_index = backlinks[out_shndx]; | ||
| 3807 | } | 3809 | } |
| 3808 | 3810 | ||
| 3809 | for (zig_object.locals()) |local_index| { | 3811 | for (zig_object.locals()) |local_index| { |
| 3810 | const local = self.symbol(local_index); | 3812 | const local = self.symbol(local_index); |
| 3811 | const atom_ptr = local.atom(self) orelse continue; | 3813 | local.output_section_index = backlinks[local.output_section_index]; |
| 3812 | if (!atom_ptr.flags.alive) continue; | ||
| 3813 | const out_shndx = local.outputShndx() orelse continue; | ||
| 3814 | local.output_section_index = backlinks[out_shndx]; | ||
| 3815 | } | 3814 | } |
| 3816 | 3815 | ||
| 3817 | for (zig_object.globals()) |global_index| { | 3816 | for (zig_object.globals()) |global_index| { |
| 3818 | const global = self.symbol(global_index); | 3817 | const global = self.symbol(global_index); |
| 3819 | const atom_ptr = global.atom(self) orelse continue; | 3818 | const atom_ptr = global.atom(self) orelse continue; |
| 3820 | if (!atom_ptr.flags.alive) continue; | 3819 | if (!atom_ptr.flags.alive) continue; |
| 3820 | // TODO claim unresolved for objects | ||
| 3821 | if (global.file(self).?.index() != zig_object.index) continue; | 3821 | if (global.file(self).?.index() != zig_object.index) continue; |
| 3822 | const out_shndx = global.outputShndx() orelse continue; | 3822 | const out_shndx = global.outputShndx() orelse continue; |
| 3823 | global.output_section_index = backlinks[out_shndx]; | 3823 | global.output_section_index = backlinks[out_shndx]; |
src/link/Elf/Symbol.zig+2| ... | @@ -223,6 +223,8 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void { | ... | @@ -223,6 +223,8 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void { |
| 223 | const st_shndx = blk: { | 223 | const st_shndx = blk: { |
| 224 | if (symbol.flags.has_copy_rel) break :blk elf_file.copy_rel_section_index.?; | 224 | if (symbol.flags.has_copy_rel) break :blk elf_file.copy_rel_section_index.?; |
| 225 | if (file_ptr == .shared_object or esym.st_shndx == elf.SHN_UNDEF) break :blk elf.SHN_UNDEF; | 225 | if (file_ptr == .shared_object or esym.st_shndx == elf.SHN_UNDEF) break :blk elf.SHN_UNDEF; |
| 226 | // TODO I think this is wrong and obsolete | ||
| 227 | if (elf_file.isObject() and st_type == elf.STT_SECTION) break :blk symbol.outputShndx().?; | ||
| 226 | if (symbol.atom(elf_file) == null and file_ptr != .linker_defined) | 228 | if (symbol.atom(elf_file) == null and file_ptr != .linker_defined) |
| 227 | break :blk elf.SHN_ABS; | 229 | break :blk elf.SHN_ABS; |
| 228 | break :blk symbol.outputShndx() orelse elf.SHN_UNDEF; | 230 | break :blk symbol.outputShndx() orelse elf.SHN_UNDEF; |
src/link/Elf/ZigObject.zig+42-12| ... | @@ -87,7 +87,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void { | ... | @@ -87,7 +87,7 @@ pub fn init(self: *ZigObject, elf_file: *Elf) !void { |
| 87 | const esym_index = try self.addLocalEsym(gpa); | 87 | const esym_index = try self.addLocalEsym(gpa); |
| 88 | const esym = &self.local_esyms.items(.elf_sym)[esym_index]; | 88 | const esym = &self.local_esyms.items(.elf_sym)[esym_index]; |
| 89 | esym.st_name = name_off; | 89 | esym.st_name = name_off; |
| 90 | esym.st_info |= elf.STT_FILE; | 90 | esym.st_info = elf.STT_FILE; |
| 91 | esym.st_shndx = elf.SHN_ABS; | 91 | esym.st_shndx = elf.SHN_ABS; |
| 92 | symbol_ptr.esym_index = esym_index; | 92 | symbol_ptr.esym_index = esym_index; |
| 93 | 93 | ||
| ... | @@ -284,6 +284,22 @@ pub fn addAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index { | ... | @@ -284,6 +284,22 @@ pub fn addAtom(self: *ZigObject, elf_file: *Elf) !Symbol.Index { |
| 284 | return symbol_index; | 284 | return symbol_index; |
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | pub fn addSectionSymbol(self: *ZigObject, shndx: u16, elf_file: *Elf) !void { | ||
| 288 | assert(elf_file.isObject()); | ||
| 289 | const gpa = elf_file.base.allocator; | ||
| 290 | const symbol_index = try elf_file.addSymbol(); | ||
| 291 | try self.local_symbols.append(gpa, symbol_index); | ||
| 292 | const symbol_ptr = elf_file.symbol(symbol_index); | ||
| 293 | symbol_ptr.file_index = self.index; | ||
| 294 | symbol_ptr.output_section_index = shndx; | ||
| 295 | |||
| 296 | const esym_index = try self.addLocalEsym(gpa); | ||
| 297 | const esym = &self.local_esyms.items(.elf_sym)[esym_index]; | ||
| 298 | esym.st_info = elf.STT_SECTION; | ||
| 299 | esym.st_shndx = shndx; | ||
| 300 | symbol_ptr.esym_index = esym_index; | ||
| 301 | } | ||
| 302 | |||
| 287 | /// TODO actually create fake input shdrs and return that instead. | 303 | /// TODO actually create fake input shdrs and return that instead. |
| 288 | pub fn inputShdr(self: ZigObject, atom_index: Atom.Index, elf_file: *Elf) Object.ElfShdr { | 304 | pub fn inputShdr(self: ZigObject, atom_index: Atom.Index, elf_file: *Elf) Object.ElfShdr { |
| 289 | _ = self; | 305 | _ = self; |
| ... | @@ -435,6 +451,16 @@ pub fn updateRelaSectionSizes(self: ZigObject, elf_file: *Elf) void { | ... | @@ -435,6 +451,16 @@ pub fn updateRelaSectionSizes(self: ZigObject, elf_file: *Elf) void { |
| 435 | pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { | 451 | pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { |
| 436 | const gpa = elf_file.base.allocator; | 452 | const gpa = elf_file.base.allocator; |
| 437 | 453 | ||
| 454 | // const getSectionSymbol = struct { | ||
| 455 | // fn getSectionSymbol(zig_object: ZigObject, shndx: u16, ctx: *Elf) Symbol.Index { | ||
| 456 | // for (zig_object.locals()) |local_index| { | ||
| 457 | // const local = ctx.symbol(local_index); | ||
| 458 | // if (local.type(ctx) == elf.STT_SECTION and local.output_section_index == shndx) | ||
| 459 | // return local.esym_index; | ||
| 460 | // } else unreachable; | ||
| 461 | // } | ||
| 462 | // }.getSectionSymbol; | ||
| 463 | |||
| 438 | for (&[_]?u16{ | 464 | for (&[_]?u16{ |
| 439 | elf_file.zig_text_rela_section_index, | 465 | elf_file.zig_text_rela_section_index, |
| 440 | elf_file.zig_data_rel_ro_rela_section_index, | 466 | elf_file.zig_data_rel_ro_rela_section_index, |
| ... | @@ -453,8 +479,13 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { | ... | @@ -453,8 +479,13 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { |
| 453 | 479 | ||
| 454 | while (true) { | 480 | while (true) { |
| 455 | for (atom.relocs(elf_file)) |rel| { | 481 | for (atom.relocs(elf_file)) |rel| { |
| 456 | var r_sym = rel.r_sym() & symbol_mask; | 482 | const target = elf_file.symbol(self.symbol(rel.r_sym())); |
| 457 | if (self.isGlobal(rel.r_sym())) r_sym += @intCast(self.local_esyms.slice().len + 1); | 483 | const r_offset = target.value + rel.r_offset; |
| 484 | const r_sym: u32 = if (target.flags.global) | ||
| 485 | (target.esym_index & symbol_mask) + @as(u32, @intCast(self.local_esyms.slice().len)) | ||
| 486 | else | ||
| 487 | target.esym_index; | ||
| 488 | // getSectionSymbol(self, target.outputShndx().?, elf_file); | ||
| 458 | const r_type = switch (rel.r_type()) { | 489 | const r_type = switch (rel.r_type()) { |
| 459 | Elf.R_X86_64_ZIG_GOT32, | 490 | Elf.R_X86_64_ZIG_GOT32, |
| 460 | Elf.R_X86_64_ZIG_GOTPCREL, | 491 | Elf.R_X86_64_ZIG_GOTPCREL, |
| ... | @@ -462,9 +493,9 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { | ... | @@ -462,9 +493,9 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { |
| 462 | else => |r_type| r_type, | 493 | else => |r_type| r_type, |
| 463 | }; | 494 | }; |
| 464 | relocs.appendAssumeCapacity(.{ | 495 | relocs.appendAssumeCapacity(.{ |
| 465 | .r_offset = rel.r_offset, | 496 | .r_offset = r_offset, |
| 466 | .r_addend = rel.r_addend, | 497 | .r_addend = rel.r_addend, |
| 467 | .r_info = (@as(u64, @intCast(r_sym)) << 32) | r_type, | 498 | .r_info = (@as(u64, @intCast(r_sym + 1)) << 32) | r_type, |
| 468 | }); | 499 | }); |
| 469 | } | 500 | } |
| 470 | if (elf_file.atom(atom.prev_index)) |prev| { | 501 | if (elf_file.atom(atom.prev_index)) |prev| { |
| ... | @@ -485,28 +516,27 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { | ... | @@ -485,28 +516,27 @@ pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void { |
| 485 | } | 516 | } |
| 486 | } | 517 | } |
| 487 | 518 | ||
| 488 | pub fn isGlobal(self: ZigObject, index: Symbol.Index) bool { | 519 | inline fn isGlobal(index: Symbol.Index) bool { |
| 489 | _ = self; | ||
| 490 | return index & global_symbol_bit != 0; | 520 | return index & global_symbol_bit != 0; |
| 491 | } | 521 | } |
| 492 | 522 | ||
| 493 | pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index { | 523 | pub fn symbol(self: ZigObject, index: Symbol.Index) Symbol.Index { |
| 494 | const actual_index = index & symbol_mask; | 524 | const actual_index = index & symbol_mask; |
| 495 | if (self.isGlobal(index)) return self.global_symbols.items[actual_index]; | 525 | if (isGlobal(index)) return self.global_symbols.items[actual_index]; |
| 496 | return self.local_symbols.items[actual_index]; | 526 | return self.local_symbols.items[actual_index]; |
| 497 | } | 527 | } |
| 498 | 528 | ||
| 499 | pub fn elfSym(self: *ZigObject, index: Symbol.Index) *elf.Elf64_Sym { | 529 | pub fn elfSym(self: *ZigObject, index: Symbol.Index) *elf.Elf64_Sym { |
| 500 | const actual_index = index & symbol_mask; | 530 | const actual_index = index & symbol_mask; |
| 501 | if (self.isGlobal(index)) return &self.global_esyms.items(.elf_sym)[actual_index]; | 531 | if (isGlobal(index)) return &self.global_esyms.items(.elf_sym)[actual_index]; |
| 502 | return &self.local_esyms.items(.elf_sym)[actual_index]; | 532 | return &self.local_esyms.items(.elf_sym)[actual_index]; |
| 503 | } | 533 | } |
| 504 | 534 | ||
| 505 | pub fn locals(self: *ZigObject) []const Symbol.Index { | 535 | pub fn locals(self: ZigObject) []const Symbol.Index { |
| 506 | return self.local_symbols.items; | 536 | return self.local_symbols.items; |
| 507 | } | 537 | } |
| 508 | 538 | ||
| 509 | pub fn globals(self: *ZigObject) []const Symbol.Index { | 539 | pub fn globals(self: ZigObject) []const Symbol.Index { |
| 510 | return self.global_symbols.items; | 540 | return self.global_symbols.items; |
| 511 | } | 541 | } |
| 512 | 542 |
src/link/Elf/file.zig+2-1| ... | @@ -136,7 +136,8 @@ pub const File = union(enum) { | ... | @@ -136,7 +136,8 @@ pub const File = union(enum) { |
| 136 | if (local.atom(elf_file)) |atom| if (!atom.flags.alive) continue; | 136 | if (local.atom(elf_file)) |atom| if (!atom.flags.alive) continue; |
| 137 | const esym = local.elfSym(elf_file); | 137 | const esym = local.elfSym(elf_file); |
| 138 | switch (esym.st_type()) { | 138 | switch (esym.st_type()) { |
| 139 | elf.STT_SECTION, elf.STT_NOTYPE => continue, | 139 | elf.STT_SECTION => if (!elf_file.isObject()) continue, |
| 140 | elf.STT_NOTYPE => continue, | ||
| 140 | else => {}, | 141 | else => {}, |
| 141 | } | 142 | } |
| 142 | local.flags.output_symtab = true; | 143 | local.flags.output_symtab = true; |