| author | |
| committer | |
| log | 1f8dd27e40bb455da85bfb1ae655ad63bc05ea08 |
| tree | 618b69cfa2785761e3846cad801bb3c31a0068e9 |
| parent | b1fcf0ed8f435b834f21a3d57c03f5c0333c6fd9 |
3 files changed, 58 insertions(+), 14 deletions(-)
src/link/Elf.zig+11-8| ... | @@ -1446,8 +1446,6 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) | ... | @@ -1446,8 +1446,6 @@ pub fn flushObject(self: *Elf, comp: *Compilation, module_obj_path: ?[]const u8) |
| 1446 | // Now, we are ready to resolve the symbols across all input files. | 1446 | // Now, we are ready to resolve the symbols across all input files. |
| 1447 | // We will first resolve the files in the ZigObject, next in the parsed | 1447 | // We will first resolve the files in the ZigObject, next in the parsed |
| 1448 | // input Object files. | 1448 | // input Object files. |
| 1449 | // Any qualifing unresolved symbol will be upgraded to an absolute, weak | ||
| 1450 | // symbol for potential resolution at load-time. | ||
| 1451 | self.resolveSymbols(); | 1449 | self.resolveSymbols(); |
| 1452 | self.markEhFrameAtomsDead(); | 1450 | self.markEhFrameAtomsDead(); |
| 1453 | self.claimUnresolvedObject(); | 1451 | self.claimUnresolvedObject(); |
| ... | @@ -4037,11 +4035,10 @@ fn sortShdrs(self: *Elf) !void { | ... | @@ -4037,11 +4035,10 @@ fn sortShdrs(self: *Elf) !void { |
| 4037 | shdr.sh_info = self.plt_section_index.?; | 4035 | shdr.sh_info = self.plt_section_index.?; |
| 4038 | } | 4036 | } |
| 4039 | 4037 | ||
| 4040 | for (self.shdrs.items) |*shdr| { | 4038 | if (self.eh_frame_rela_section_index) |index| { |
| 4041 | if (shdr.sh_type == elf.SHT_RELA and shdr.sh_flags & elf.SHF_INFO_LINK != 0) { | 4039 | const shdr = &self.shdrs.items[index]; |
| 4042 | shdr.sh_link = self.symtab_section_index.?; | 4040 | shdr.sh_link = self.symtab_section_index.?; |
| 4043 | shdr.sh_info = backlinks[shdr.sh_info]; | 4041 | shdr.sh_info = self.eh_frame_section_index.?; |
| 4044 | } | ||
| 4045 | } | 4042 | } |
| 4046 | 4043 | ||
| 4047 | { | 4044 | { |
| ... | @@ -4122,6 +4119,12 @@ fn sortShdrs(self: *Elf) !void { | ... | @@ -4122,6 +4119,12 @@ fn sortShdrs(self: *Elf) !void { |
| 4122 | global.output_section_index = backlinks[out_shndx]; | 4119 | global.output_section_index = backlinks[out_shndx]; |
| 4123 | } | 4120 | } |
| 4124 | } | 4121 | } |
| 4122 | |||
| 4123 | for (self.output_rela_sections.keys(), self.output_rela_sections.values()) |shndx, sec| { | ||
| 4124 | const shdr = &self.shdrs.items[sec.shndx]; | ||
| 4125 | shdr.sh_link = self.symtab_section_index.?; | ||
| 4126 | shdr.sh_info = shndx; | ||
| 4127 | } | ||
| 4125 | } | 4128 | } |
| 4126 | 4129 | ||
| 4127 | fn updateSectionSizes(self: *Elf) !void { | 4130 | fn updateSectionSizes(self: *Elf) !void { |
| ... | @@ -5009,7 +5012,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { | ... | @@ -5009,7 +5012,7 @@ fn writeSyntheticSectionsObject(self: *Elf) !void { |
| 5009 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; | 5012 | const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow; |
| 5010 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); | 5013 | var buffer = try std.ArrayList(u8).initCapacity(gpa, sh_size); |
| 5011 | defer buffer.deinit(); | 5014 | defer buffer.deinit(); |
| 5012 | try eh_frame.writeEhFrame(self, buffer.writer()); | 5015 | try eh_frame.writeEhFrameObject(self, buffer.writer()); |
| 5013 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); | 5016 | try self.base.file.?.pwriteAll(buffer.items, shdr.sh_offset); |
| 5014 | } | 5017 | } |
| 5015 | if (self.eh_frame_rela_section_index) |shndx| { | 5018 | if (self.eh_frame_rela_section_index) |shndx| { |
src/link/Elf/Object.zig+9-5| ... | @@ -687,7 +687,6 @@ pub fn initRelaSections(self: Object, elf_file: *Elf) !void { | ... | @@ -687,7 +687,6 @@ pub fn initRelaSections(self: Object, elf_file: *Elf) !void { |
| 687 | const out_shdr = &elf_file.shdrs.items[out_shndx]; | 687 | const out_shdr = &elf_file.shdrs.items[out_shndx]; |
| 688 | out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela); | 688 | out_shdr.sh_addralign = @alignOf(elf.Elf64_Rela); |
| 689 | out_shdr.sh_entsize = @sizeOf(elf.Elf64_Rela); | 689 | out_shdr.sh_entsize = @sizeOf(elf.Elf64_Rela); |
| 690 | out_shdr.sh_info = self.initOutputSection(elf_file, atom.inputShdr(elf_file)) catch unreachable; | ||
| 691 | } | 690 | } |
| 692 | } | 691 | } |
| 693 | 692 | ||
| ... | @@ -695,13 +694,18 @@ pub fn addAtomsToRelaSections(self: Object, elf_file: *Elf) !void { | ... | @@ -695,13 +694,18 @@ pub fn addAtomsToRelaSections(self: Object, elf_file: *Elf) !void { |
| 695 | for (self.atoms.items) |atom_index| { | 694 | for (self.atoms.items) |atom_index| { |
| 696 | const atom = elf_file.atom(atom_index) orelse continue; | 695 | const atom = elf_file.atom(atom_index) orelse continue; |
| 697 | if (!atom.flags.alive) continue; | 696 | if (!atom.flags.alive) continue; |
| 698 | const shndx = atom.relocsShndx() orelse continue; | 697 | const shndx = blk: { |
| 699 | const shdr = self.shdrs.items[shndx]; | 698 | const shndx = atom.relocsShndx() orelse continue; |
| 700 | const out_shndx = self.initOutputSection(elf_file, shdr) catch unreachable; | 699 | const shdr = self.shdrs.items[shndx]; |
| 700 | break :blk self.initOutputSection(elf_file, shdr) catch unreachable; | ||
| 701 | }; | ||
| 702 | const shdr = &elf_file.shdrs.items[shndx]; | ||
| 703 | shdr.sh_info = atom.outputShndx().?; | ||
| 704 | shdr.sh_link = elf_file.symtab_section_index.?; | ||
| 701 | 705 | ||
| 702 | const gpa = elf_file.base.allocator; | 706 | const gpa = elf_file.base.allocator; |
| 703 | const gop = try elf_file.output_rela_sections.getOrPut(gpa, atom.outputShndx().?); | 707 | const gop = try elf_file.output_rela_sections.getOrPut(gpa, atom.outputShndx().?); |
| 704 | if (!gop.found_existing) gop.value_ptr.* = .{ .shndx = out_shndx }; | 708 | if (!gop.found_existing) gop.value_ptr.* = .{ .shndx = shndx }; |
| 705 | try gop.value_ptr.atom_list.append(gpa, atom_index); | 709 | try gop.value_ptr.atom_list.append(gpa, atom_index); |
| 706 | } | 710 | } |
| 707 | } | 711 | } |
src/link/Elf/eh_frame.zig+38-1| ... | @@ -268,7 +268,11 @@ pub fn calcEhFrameSize(elf_file: *Elf) !usize { | ... | @@ -268,7 +268,11 @@ pub fn calcEhFrameSize(elf_file: *Elf) !usize { |
| 268 | } | 268 | } |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | return offset + 4; // NULL terminator | 271 | if (!elf_file.isRelocatable()) { |
| 272 | offset += 4; // NULL terminator | ||
| 273 | } | ||
| 274 | |||
| 275 | return offset; | ||
| 272 | } | 276 | } |
| 273 | 277 | ||
| 274 | pub fn calcEhFrameHdrSize(elf_file: *Elf) usize { | 278 | pub fn calcEhFrameHdrSize(elf_file: *Elf) usize { |
| ... | @@ -373,6 +377,39 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void { | ... | @@ -373,6 +377,39 @@ pub fn writeEhFrame(elf_file: *Elf, writer: anytype) !void { |
| 373 | try writer.writeInt(u32, 0, .little); | 377 | try writer.writeInt(u32, 0, .little); |
| 374 | } | 378 | } |
| 375 | 379 | ||
| 380 | pub fn writeEhFrameObject(elf_file: *Elf, writer: anytype) !void { | ||
| 381 | const gpa = elf_file.base.allocator; | ||
| 382 | |||
| 383 | for (elf_file.objects.items) |index| { | ||
| 384 | const object = elf_file.file(index).?.object; | ||
| 385 | |||
| 386 | for (object.cies.items) |cie| { | ||
| 387 | if (!cie.alive) continue; | ||
| 388 | try writer.writeAll(cie.data(elf_file)); | ||
| 389 | } | ||
| 390 | } | ||
| 391 | |||
| 392 | for (elf_file.objects.items) |index| { | ||
| 393 | const object = elf_file.file(index).?.object; | ||
| 394 | |||
| 395 | for (object.fdes.items) |fde| { | ||
| 396 | if (!fde.alive) continue; | ||
| 397 | |||
| 398 | const contents = try gpa.dupe(u8, fde.data(elf_file)); | ||
| 399 | defer gpa.free(contents); | ||
| 400 | |||
| 401 | std.mem.writeInt( | ||
| 402 | i32, | ||
| 403 | contents[4..8], | ||
| 404 | @truncate(@as(i64, @intCast(fde.out_offset + 4)) - @as(i64, @intCast(fde.cie(elf_file).out_offset))), | ||
| 405 | .little, | ||
| 406 | ); | ||
| 407 | |||
| 408 | try writer.writeAll(contents); | ||
| 409 | } | ||
| 410 | } | ||
| 411 | } | ||
| 412 | |||
| 376 | fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela) elf.Elf64_Rela { | 413 | fn emitReloc(elf_file: *Elf, rec: anytype, sym: *const Symbol, rel: elf.Elf64_Rela) elf.Elf64_Rela { |
| 377 | const r_offset = rec.address(elf_file) + rel.r_offset - rec.offset; | 414 | const r_offset = rec.address(elf_file) + rel.r_offset - rec.offset; |
| 378 | const r_type = rel.r_type(); | 415 | const r_type = rel.r_type(); |