| author | |
| committer | |
| log | 85d451f96cd8f2854fa6a092625b8a2f3c474a73 |
| tree | 0c001659b2021fe860cb982f137aacf271a5e668 |
| parent | 7be983ac9217a596b7f35e7ef4c49fda0270e10b |
4 files changed, 110 insertions(+), 21 deletions(-)
src/link/Elf.zig+62-6| ... | @@ -762,6 +762,7 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -762,6 +762,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 762 | .name = ".zig.got", | 762 | .name = ".zig.got", |
| 763 | .phdr_index = self.phdr_zig_got_index.?, | 763 | .phdr_index = self.phdr_zig_got_index.?, |
| 764 | .alignment = ptr_size, | 764 | .alignment = ptr_size, |
| 765 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | ||
| 765 | }); | 766 | }); |
| 766 | } | 767 | } |
| 767 | 768 | ||
| ... | @@ -785,7 +786,7 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -785,7 +786,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 785 | 786 | ||
| 786 | if (self.zig_bss_section_index == null) { | 787 | if (self.zig_bss_section_index == null) { |
| 787 | self.zig_bss_section_index = try self.allocateAllocSection(.{ | 788 | self.zig_bss_section_index = try self.allocateAllocSection(.{ |
| 788 | .name = ".bss.zig", | 789 | .name = ".zig.bss", |
| 789 | .phdr_index = self.phdr_zig_load_zerofill_index.?, | 790 | .phdr_index = self.phdr_zig_load_zerofill_index.?, |
| 790 | .alignment = ptr_size, | 791 | .alignment = ptr_size, |
| 791 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, | 792 | .flags = elf.SHF_ALLOC | elf.SHF_WRITE, |
| ... | @@ -1558,7 +1559,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1558,7 +1559,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1558 | for (zig_module.atoms.items) |atom_index| { | 1559 | for (zig_module.atoms.items) |atom_index| { |
| 1559 | const atom_ptr = self.atom(atom_index) orelse continue; | 1560 | const atom_ptr = self.atom(atom_index) orelse continue; |
| 1560 | if (!atom_ptr.flags.alive) continue; | 1561 | if (!atom_ptr.flags.alive) continue; |
| 1561 | const shdr = &self.shdrs.items[atom_ptr.outputShndx().?]; | 1562 | const out_shndx = atom_ptr.outputShndx() orelse continue; |
| 1563 | const shdr = &self.shdrs.items[out_shndx]; | ||
| 1562 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | 1564 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| 1563 | const code = try zig_module.codeAlloc(self, atom_index); | 1565 | const code = try zig_module.codeAlloc(self, atom_index); |
| 1564 | defer gpa.free(code); | 1566 | defer gpa.free(code); |
| ... | @@ -3744,6 +3746,9 @@ fn initSections(self: *Elf) !void { | ... | @@ -3744,6 +3746,9 @@ fn initSections(self: *Elf) !void { |
| 3744 | const needs_rela_dyn = blk: { | 3746 | const needs_rela_dyn = blk: { |
| 3745 | if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or | 3747 | if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or |
| 3746 | self.copy_rel.symbols.items.len > 0) break :blk true; | 3748 | self.copy_rel.symbols.items.len > 0) break :blk true; |
| 3749 | if (self.zig_module_index) |index| { | ||
| 3750 | if (self.file(index).?.zig_module.num_dynrelocs > 0) break :blk true; | ||
| 3751 | } | ||
| 3747 | for (self.objects.items) |index| { | 3752 | for (self.objects.items) |index| { |
| 3748 | if (self.file(index).?.object.num_dynrelocs > 0) break :blk true; | 3753 | if (self.file(index).?.object.num_dynrelocs > 0) break :blk true; |
| 3749 | } | 3754 | } |
| ... | @@ -4243,6 +4248,33 @@ fn sortSections(self: *Elf) !void { | ... | @@ -4243,6 +4248,33 @@ fn sortSections(self: *Elf) !void { |
| 4243 | shdr.sh_link = self.dynsymtab_section_index.?; | 4248 | shdr.sh_link = self.dynsymtab_section_index.?; |
| 4244 | shdr.sh_info = self.plt_section_index.?; | 4249 | shdr.sh_info = self.plt_section_index.?; |
| 4245 | } | 4250 | } |
| 4251 | |||
| 4252 | if (self.zig_module_index) |index| { | ||
| 4253 | const zig_module = self.file(index).?.zig_module; | ||
| 4254 | for (zig_module.atoms.items) |atom_index| { | ||
| 4255 | const atom_ptr = self.atom(atom_index) orelse continue; | ||
| 4256 | if (!atom_ptr.flags.alive) continue; | ||
| 4257 | const out_shndx = atom_ptr.outputShndx() orelse continue; | ||
| 4258 | atom_ptr.output_section_index = backlinks[out_shndx]; | ||
| 4259 | } | ||
| 4260 | |||
| 4261 | for (zig_module.locals()) |local_index| { | ||
| 4262 | const local = self.symbol(local_index); | ||
| 4263 | const atom_ptr = local.atom(self) orelse continue; | ||
| 4264 | if (!atom_ptr.flags.alive) continue; | ||
| 4265 | const out_shndx = local.outputShndx() orelse continue; | ||
| 4266 | local.output_section_index = backlinks[out_shndx]; | ||
| 4267 | } | ||
| 4268 | |||
| 4269 | for (zig_module.globals()) |global_index| { | ||
| 4270 | const global = self.symbol(global_index); | ||
| 4271 | const atom_ptr = global.atom(self) orelse continue; | ||
| 4272 | if (!atom_ptr.flags.alive) continue; | ||
| 4273 | if (global.file(self).?.index() != index) continue; | ||
| 4274 | const out_shndx = global.outputShndx() orelse continue; | ||
| 4275 | global.output_section_index = backlinks[out_shndx]; | ||
| 4276 | } | ||
| 4277 | } | ||
| 4246 | } | 4278 | } |
| 4247 | 4279 | ||
| 4248 | fn updateSectionSizes(self: *Elf) !void { | 4280 | fn updateSectionSizes(self: *Elf) !void { |
| ... | @@ -4286,6 +4318,9 @@ fn updateSectionSizes(self: *Elf) !void { | ... | @@ -4286,6 +4318,9 @@ fn updateSectionSizes(self: *Elf) !void { |
| 4286 | 4318 | ||
| 4287 | if (self.rela_dyn_section_index) |shndx| { | 4319 | if (self.rela_dyn_section_index) |shndx| { |
| 4288 | var num = self.got.numRela(self) + self.copy_rel.numRela(); | 4320 | var num = self.got.numRela(self) + self.copy_rel.numRela(); |
| 4321 | if (self.zig_module_index) |index| { | ||
| 4322 | num += self.file(index).?.zig_module.num_dynrelocs; | ||
| 4323 | } | ||
| 4289 | for (self.objects.items) |index| { | 4324 | for (self.objects.items) |index| { |
| 4290 | num += self.file(index).?.object.num_dynrelocs; | 4325 | num += self.file(index).?.object.num_dynrelocs; |
| 4291 | } | 4326 | } |
| ... | @@ -4373,9 +4408,10 @@ fn shdrToPhdrFlags(sh_flags: u64) u32 { | ... | @@ -4373,9 +4408,10 @@ fn shdrToPhdrFlags(sh_flags: u64) u32 { |
| 4373 | fn calcNumberOfSegments(self: *Elf) usize { | 4408 | fn calcNumberOfSegments(self: *Elf) usize { |
| 4374 | var count: usize = 0; | 4409 | var count: usize = 0; |
| 4375 | var flags: u64 = 0; | 4410 | var flags: u64 = 0; |
| 4376 | for (self.shdrs.items) |shdr| { | 4411 | for (self.shdrs.items, 0..) |shdr, shndx| { |
| 4377 | if (shdr.sh_type == elf.SHT_NULL) continue; | 4412 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 4378 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; | 4413 | if (shdr.sh_flags & elf.SHF_ALLOC == 0) continue; |
| 4414 | if (self.isZigSection(@intCast(shndx))) continue; | ||
| 4379 | if (flags != shdrToPhdrFlags(shdr.sh_flags)) count += 1; | 4415 | if (flags != shdrToPhdrFlags(shdr.sh_flags)) count += 1; |
| 4380 | flags = shdrToPhdrFlags(shdr.sh_flags); | 4416 | flags = shdrToPhdrFlags(shdr.sh_flags); |
| 4381 | } | 4417 | } |
| ... | @@ -4474,7 +4510,10 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void { | ... | @@ -4474,7 +4510,10 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void { |
| 4474 | } | 4510 | } |
| 4475 | } | 4511 | } |
| 4476 | } | 4512 | } |
| 4477 | covers[nphdrs - 1].len = shndx - covers[nphdrs - 1].start; | 4513 | |
| 4514 | if (nphdrs > 0) { | ||
| 4515 | covers[nphdrs - 1].len = shndx - covers[nphdrs - 1].start; | ||
| 4516 | } | ||
| 4478 | 4517 | ||
| 4479 | // Now we can proceed with allocating the sections in virtual memory. | 4518 | // Now we can proceed with allocating the sections in virtual memory. |
| 4480 | // As the base address we take the end address of the PHDR table. | 4519 | // As the base address we take the end address of the PHDR table. |
| ... | @@ -4647,6 +4686,7 @@ fn writeAtoms(self: *Elf) !void { | ... | @@ -4647,6 +4686,7 @@ fn writeAtoms(self: *Elf) !void { |
| 4647 | undefs.deinit(); | 4686 | undefs.deinit(); |
| 4648 | } | 4687 | } |
| 4649 | 4688 | ||
| 4689 | // TODO iterate over `output_sections` directly | ||
| 4650 | for (self.shdrs.items, 0..) |shdr, shndx| { | 4690 | for (self.shdrs.items, 0..) |shdr, shndx| { |
| 4651 | if (shdr.sh_type == elf.SHT_NULL) continue; | 4691 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 4652 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | 4692 | if (shdr.sh_type == elf.SHT_NOBITS) continue; |
| ... | @@ -5830,7 +5870,10 @@ fn fmtDumpState( | ... | @@ -5830,7 +5870,10 @@ fn fmtDumpState( |
| 5830 | if (self.zig_module_index) |index| { | 5870 | if (self.zig_module_index) |index| { |
| 5831 | const zig_module = self.file(index).?.zig_module; | 5871 | const zig_module = self.file(index).?.zig_module; |
| 5832 | try writer.print("zig_module({d}) : {s}\n", .{ index, zig_module.path }); | 5872 | try writer.print("zig_module({d}) : {s}\n", .{ index, zig_module.path }); |
| 5833 | try writer.print("{}\n", .{zig_module.fmtSymtab(self)}); | 5873 | try writer.print("{}{}\n", .{ |
| 5874 | zig_module.fmtAtoms(self), | ||
| 5875 | zig_module.fmtSymtab(self), | ||
| 5876 | }); | ||
| 5834 | } | 5877 | } |
| 5835 | 5878 | ||
| 5836 | for (self.objects.items) |index| { | 5879 | for (self.objects.items) |index| { |
| ... | @@ -5872,7 +5915,7 @@ fn fmtDumpState( | ... | @@ -5872,7 +5915,7 @@ fn fmtDumpState( |
| 5872 | self.fmtShdr(shdr), | 5915 | self.fmtShdr(shdr), |
| 5873 | }); | 5916 | }); |
| 5874 | } | 5917 | } |
| 5875 | try writer.writeAll("Output phdrs\n"); | 5918 | try writer.writeAll("\nOutput phdrs\n"); |
| 5876 | for (self.phdrs.items, 0..) |phdr, phndx| { | 5919 | for (self.phdrs.items, 0..) |phdr, phndx| { |
| 5877 | try writer.print("phdr{d} : {}\n", .{ phndx, self.fmtPhdr(phdr) }); | 5920 | try writer.print("phdr{d} : {}\n", .{ phndx, self.fmtPhdr(phdr) }); |
| 5878 | } | 5921 | } |
| ... | @@ -5983,6 +6026,19 @@ pub const null_sym = elf.Elf64_Sym{ | ... | @@ -5983,6 +6026,19 @@ pub const null_sym = elf.Elf64_Sym{ |
| 5983 | .st_size = 0, | 6026 | .st_size = 0, |
| 5984 | }; | 6027 | }; |
| 5985 | 6028 | ||
| 6029 | pub const null_shdr = elf.Elf64_Shdr{ | ||
| 6030 | .sh_name = 0, | ||
| 6031 | .sh_type = 0, | ||
| 6032 | .sh_flags = 0, | ||
| 6033 | .sh_addr = 0, | ||
| 6034 | .sh_offset = 0, | ||
| 6035 | .sh_size = 0, | ||
| 6036 | .sh_link = 0, | ||
| 6037 | .sh_info = 0, | ||
| 6038 | .sh_addralign = 0, | ||
| 6039 | .sh_entsize = 0, | ||
| 6040 | }; | ||
| 6041 | |||
| 5986 | const SystemLib = struct { | 6042 | const SystemLib = struct { |
| 5987 | needed: bool = false, | 6043 | needed: bool = false, |
| 5988 | path: []const u8, | 6044 | path: []const u8, |
src/link/Elf/Atom.zig+21-13| ... | @@ -50,8 +50,11 @@ pub fn file(self: Atom, elf_file: *Elf) ?File { | ... | @@ -50,8 +50,11 @@ pub fn file(self: Atom, elf_file: *Elf) ?File { |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | pub fn inputShdr(self: Atom, elf_file: *Elf) Object.ElfShdr { | 52 | pub fn inputShdr(self: Atom, elf_file: *Elf) Object.ElfShdr { |
| 53 | const object = self.file(elf_file).?.object; | 53 | return switch (self.file(elf_file).?) { |
| 54 | return object.shdrs.items[self.input_section_index]; | 54 | .object => |x| x.shdrs.items[self.input_section_index], |
| 55 | .zig_module => |x| x.inputShdr(self.atom_index, elf_file), | ||
| 56 | else => unreachable, | ||
| 57 | }; | ||
| 55 | } | 58 | } |
| 56 | 59 | ||
| 57 | pub fn outputShndx(self: Atom) ?u16 { | 60 | pub fn outputShndx(self: Atom) ?u16 { |
| ... | @@ -199,7 +202,7 @@ pub fn allocate(self: *Atom, elf_file: *Elf) !void { | ... | @@ -199,7 +202,7 @@ pub fn allocate(self: *Atom, elf_file: *Elf) !void { |
| 199 | _ = free_list.swapRemove(i); | 202 | _ = free_list.swapRemove(i); |
| 200 | } | 203 | } |
| 201 | 204 | ||
| 202 | self.flags.allocated = true; | 205 | self.flags.alive = true; |
| 203 | } | 206 | } |
| 204 | 207 | ||
| 205 | pub fn shrink(self: *Atom, elf_file: *Elf) void { | 208 | pub fn shrink(self: *Atom, elf_file: *Elf) void { |
| ... | @@ -471,7 +474,11 @@ fn scanReloc( | ... | @@ -471,7 +474,11 @@ fn scanReloc( |
| 471 | elf_file: *Elf, | 474 | elf_file: *Elf, |
| 472 | ) error{OutOfMemory}!void { | 475 | ) error{OutOfMemory}!void { |
| 473 | const is_writeable = self.inputShdr(elf_file).sh_flags & elf.SHF_WRITE != 0; | 476 | const is_writeable = self.inputShdr(elf_file).sh_flags & elf.SHF_WRITE != 0; |
| 474 | const object = self.file(elf_file).?.object; | 477 | const num_dynrelocs = switch (self.file(elf_file).?) { |
| 478 | .linker_defined => unreachable, | ||
| 479 | .shared_object => unreachable, | ||
| 480 | inline else => |x| &x.num_dynrelocs, | ||
| 481 | }; | ||
| 475 | 482 | ||
| 476 | switch (action) { | 483 | switch (action) { |
| 477 | .none => {}, | 484 | .none => {}, |
| ... | @@ -500,7 +507,7 @@ fn scanReloc( | ... | @@ -500,7 +507,7 @@ fn scanReloc( |
| 500 | try self.reportTextRelocError(symbol, rel, elf_file); | 507 | try self.reportTextRelocError(symbol, rel, elf_file); |
| 501 | } | 508 | } |
| 502 | } | 509 | } |
| 503 | object.num_dynrelocs += 1; | 510 | num_dynrelocs.* += 1; |
| 504 | } else { | 511 | } else { |
| 505 | symbol.flags.needs_copy_rel = true; | 512 | symbol.flags.needs_copy_rel = true; |
| 506 | } | 513 | } |
| ... | @@ -517,7 +524,7 @@ fn scanReloc( | ... | @@ -517,7 +524,7 @@ fn scanReloc( |
| 517 | 524 | ||
| 518 | .dyn_cplt => { | 525 | .dyn_cplt => { |
| 519 | if (is_writeable) { | 526 | if (is_writeable) { |
| 520 | object.num_dynrelocs += 1; | 527 | num_dynrelocs.* += 1; |
| 521 | } else { | 528 | } else { |
| 522 | symbol.flags.needs_plt = true; | 529 | symbol.flags.needs_plt = true; |
| 523 | symbol.flags.is_canonical = true; | 530 | symbol.flags.is_canonical = true; |
| ... | @@ -532,7 +539,7 @@ fn scanReloc( | ... | @@ -532,7 +539,7 @@ fn scanReloc( |
| 532 | try self.reportTextRelocError(symbol, rel, elf_file); | 539 | try self.reportTextRelocError(symbol, rel, elf_file); |
| 533 | } | 540 | } |
| 534 | } | 541 | } |
| 535 | object.num_dynrelocs += 1; | 542 | num_dynrelocs.* += 1; |
| 536 | 543 | ||
| 537 | if (action == .ifunc) elf_file.num_ifunc_dynrelocs += 1; | 544 | if (action == .ifunc) elf_file.num_ifunc_dynrelocs += 1; |
| 538 | }, | 545 | }, |
| ... | @@ -898,9 +905,13 @@ fn resolveDynAbsReloc( | ... | @@ -898,9 +905,13 @@ fn resolveDynAbsReloc( |
| 898 | const A = rel.r_addend; | 905 | const A = rel.r_addend; |
| 899 | const S = @as(i64, @intCast(target.address(.{}, elf_file))); | 906 | const S = @as(i64, @intCast(target.address(.{}, elf_file))); |
| 900 | const is_writeable = self.inputShdr(elf_file).sh_flags & elf.SHF_WRITE != 0; | 907 | const is_writeable = self.inputShdr(elf_file).sh_flags & elf.SHF_WRITE != 0; |
| 901 | const object = self.file(elf_file).?.object; | ||
| 902 | 908 | ||
| 903 | try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, object.num_dynrelocs); | 909 | const num_dynrelocs = switch (self.file(elf_file).?) { |
| 910 | .linker_defined => unreachable, | ||
| 911 | .shared_object => unreachable, | ||
| 912 | inline else => |x| x.num_dynrelocs, | ||
| 913 | }; | ||
| 914 | try elf_file.rela_dyn.ensureUnusedCapacity(elf_file.base.allocator, num_dynrelocs); | ||
| 904 | 915 | ||
| 905 | switch (action) { | 916 | switch (action) { |
| 906 | .@"error", | 917 | .@"error", |
| ... | @@ -1165,7 +1176,7 @@ fn format2( | ... | @@ -1165,7 +1176,7 @@ fn format2( |
| 1165 | _ = unused_fmt_string; | 1176 | _ = unused_fmt_string; |
| 1166 | const atom = ctx.atom; | 1177 | const atom = ctx.atom; |
| 1167 | const elf_file = ctx.elf_file; | 1178 | const elf_file = ctx.elf_file; |
| 1168 | try writer.print("atom({d}) : {s} : @{x} : sect({d}) : align({x}) : size({x})", .{ | 1179 | try writer.print("atom({d}) : {s} : @{x} : shdr({d}) : align({x}) : size({x})", .{ |
| 1169 | atom.atom_index, atom.name(elf_file), atom.value, | 1180 | atom.atom_index, atom.name(elf_file), atom.value, |
| 1170 | atom.output_section_index, atom.alignment, atom.size, | 1181 | atom.output_section_index, atom.alignment, atom.size, |
| 1171 | }); | 1182 | }); |
| ... | @@ -1191,9 +1202,6 @@ pub const Flags = packed struct { | ... | @@ -1191,9 +1202,6 @@ pub const Flags = packed struct { |
| 1191 | 1202 | ||
| 1192 | /// Specifies if the atom has been visited during garbage collection. | 1203 | /// Specifies if the atom has been visited during garbage collection. |
| 1193 | visited: bool = false, | 1204 | visited: bool = false, |
| 1194 | |||
| 1195 | /// Specifies whether this atom has been allocated in the output section. | ||
| 1196 | allocated: bool = false, | ||
| 1197 | }; | 1205 | }; |
| 1198 | 1206 | ||
| 1199 | const x86_64 = struct { | 1207 | const x86_64 = struct { |
src/link/Elf/Symbol.zig+1-1| ... | @@ -314,7 +314,7 @@ fn format2( | ... | @@ -314,7 +314,7 @@ fn format2( |
| 314 | try writer.writeAll(" : absolute"); | 314 | try writer.writeAll(" : absolute"); |
| 315 | } | 315 | } |
| 316 | } else if (symbol.outputShndx()) |shndx| { | 316 | } else if (symbol.outputShndx()) |shndx| { |
| 317 | try writer.print(" : sect({d})", .{shndx}); | 317 | try writer.print(" : shdr({d})", .{shndx}); |
| 318 | } | 318 | } |
| 319 | if (symbol.atom(ctx.elf_file)) |atom_ptr| { | 319 | if (symbol.atom(ctx.elf_file)) |atom_ptr| { |
| 320 | try writer.print(" : atom({d})", .{atom_ptr.atom_index}); | 320 | try writer.print(" : atom({d})", .{atom_ptr.atom_index}); |
src/link/Elf/ZigModule.zig+26-1| ... | @@ -16,6 +16,8 @@ globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{}, | ... | @@ -16,6 +16,8 @@ globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{}, |
| 16 | atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, | 16 | atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, |
| 17 | relocs: std.ArrayListUnmanaged(std.ArrayListUnmanaged(elf.Elf64_Rela)) = .{}, | 17 | relocs: std.ArrayListUnmanaged(std.ArrayListUnmanaged(elf.Elf64_Rela)) = .{}, |
| 18 | 18 | ||
| 19 | num_dynrelocs: u32 = 0, | ||
| 20 | |||
| 19 | output_symtab_size: Elf.SymtabSize = .{}, | 21 | output_symtab_size: Elf.SymtabSize = .{}, |
| 20 | 22 | ||
| 21 | pub fn deinit(self: *ZigModule, allocator: Allocator) void { | 23 | pub fn deinit(self: *ZigModule, allocator: Allocator) void { |
| ... | @@ -79,6 +81,22 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index { | ... | @@ -79,6 +81,22 @@ pub fn addAtom(self: *ZigModule, elf_file: *Elf) !Symbol.Index { |
| 79 | return symbol_index; | 81 | return symbol_index; |
| 80 | } | 82 | } |
| 81 | 83 | ||
| 84 | /// TODO actually create fake input shdrs and return that instead. | ||
| 85 | pub fn inputShdr(self: ZigModule, atom_index: Atom.Index, elf_file: *Elf) Object.ElfShdr { | ||
| 86 | _ = self; | ||
| 87 | const shdr = shdr: { | ||
| 88 | const atom = elf_file.atom(atom_index) orelse break :shdr Elf.null_shdr; | ||
| 89 | const shndx = atom.outputShndx() orelse break :shdr Elf.null_shdr; | ||
| 90 | var shdr = elf_file.shdrs.items[shndx]; | ||
| 91 | shdr.sh_addr = 0; | ||
| 92 | shdr.sh_offset = 0; | ||
| 93 | shdr.sh_size = atom.size; | ||
| 94 | shdr.sh_addralign = atom.alignment.toByteUnits(1); | ||
| 95 | break :shdr shdr; | ||
| 96 | }; | ||
| 97 | return Object.ElfShdr.fromElf64Shdr(shdr) catch unreachable; | ||
| 98 | } | ||
| 99 | |||
| 82 | pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { | 100 | pub fn resolveSymbols(self: *ZigModule, elf_file: *Elf) void { |
| 83 | for (self.globals(), 0..) |index, i| { | 101 | for (self.globals(), 0..) |index, i| { |
| 84 | const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000; | 102 | const esym_index = @as(Symbol.Index, @intCast(i)) | 0x10000000; |
| ... | @@ -145,6 +163,8 @@ pub fn scanRelocs(self: *ZigModule, elf_file: *Elf, undefs: anytype) !void { | ... | @@ -145,6 +163,8 @@ pub fn scanRelocs(self: *ZigModule, elf_file: *Elf, undefs: anytype) !void { |
| 145 | for (self.atoms.items) |atom_index| { | 163 | for (self.atoms.items) |atom_index| { |
| 146 | const atom = elf_file.atom(atom_index) orelse continue; | 164 | const atom = elf_file.atom(atom_index) orelse continue; |
| 147 | if (!atom.flags.alive) continue; | 165 | if (!atom.flags.alive) continue; |
| 166 | const shdr = atom.inputShdr(elf_file); | ||
| 167 | if (shdr.sh_type == elf.SHT_NOBITS) continue; | ||
| 148 | if (atom.scanRelocsRequiresCode(elf_file)) { | 168 | if (atom.scanRelocsRequiresCode(elf_file)) { |
| 149 | // TODO ideally we don't have to fetch the code here. | 169 | // TODO ideally we don't have to fetch the code here. |
| 150 | // Perhaps it would make sense to save the code until flushModule where we | 170 | // Perhaps it would make sense to save the code until flushModule where we |
| ... | @@ -273,7 +293,10 @@ pub fn codeAlloc(self: ZigModule, elf_file: *Elf, atom_index: Atom.Index) ![]u8 | ... | @@ -273,7 +293,10 @@ pub fn codeAlloc(self: ZigModule, elf_file: *Elf, atom_index: Atom.Index) ![]u8 |
| 273 | const code = try gpa.alloc(u8, size); | 293 | const code = try gpa.alloc(u8, size); |
| 274 | errdefer gpa.free(code); | 294 | errdefer gpa.free(code); |
| 275 | const amt = try elf_file.base.file.?.preadAll(code, file_offset); | 295 | const amt = try elf_file.base.file.?.preadAll(code, file_offset); |
| 276 | if (amt != code.len) return error.InputOutput; | 296 | if (amt != code.len) { |
| 297 | log.err("fetching code for {s} failed", .{atom.name(elf_file)}); | ||
| 298 | return error.InputOutput; | ||
| 299 | } | ||
| 277 | return code; | 300 | return code; |
| 278 | } | 301 | } |
| 279 | 302 | ||
| ... | @@ -334,11 +357,13 @@ fn formatAtoms( | ... | @@ -334,11 +357,13 @@ fn formatAtoms( |
| 334 | const assert = std.debug.assert; | 357 | const assert = std.debug.assert; |
| 335 | const std = @import("std"); | 358 | const std = @import("std"); |
| 336 | const elf = std.elf; | 359 | const elf = std.elf; |
| 360 | const log = std.log.scoped(.link); | ||
| 337 | 361 | ||
| 338 | const Allocator = std.mem.Allocator; | 362 | const Allocator = std.mem.Allocator; |
| 339 | const Atom = @import("Atom.zig"); | 363 | const Atom = @import("Atom.zig"); |
| 340 | const Elf = @import("../Elf.zig"); | 364 | const Elf = @import("../Elf.zig"); |
| 341 | const File = @import("file.zig").File; | 365 | const File = @import("file.zig").File; |
| 342 | const Module = @import("../../Module.zig"); | 366 | const Module = @import("../../Module.zig"); |
| 367 | const Object = @import("Object.zig"); | ||
| 343 | const Symbol = @import("Symbol.zig"); | 368 | const Symbol = @import("Symbol.zig"); |
| 344 | const ZigModule = @This(); | 369 | const ZigModule = @This(); |