diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-13 14:46:45 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-13 14:46:45 +0100 |
| commit | b9cca3b63dbcedadbda1c884e5b3333c8458b30d (patch) | |
| tree | 48279d466c04e4771d4b315db590c9bbfcbd4868 /src | |
| parent | 153ba46a5b20f178d48ef2f09e0e638a3749af0e (diff) | |
| parent | 7ba2453b8ec56ccacfccc466183e1aaafbd5210e (diff) | |
| download | zig-b9cca3b63dbcedadbda1c884e5b3333c8458b30d.tar.gz zig-b9cca3b63dbcedadbda1c884e5b3333c8458b30d.zip | |
Merge pull request #19257 from ziglang/elf-aarch64-thunks-2
elf+aarch64: fix off-by-one in converging on groups interleaved with thunks
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/Elf.zig | 34 | ||||
| -rw-r--r-- | src/link/Elf/thunks.zig | 8 |
2 files changed, 31 insertions, 11 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig index d26f49ca09..e6182b4333 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -4565,6 +4565,22 @@ fn writeAtoms(self: *Elf) !void { try self.base.file.?.pwriteAll(buffer, sh_offset); } + if (self.requiresThunks()) { + var buffer = std.ArrayList(u8).init(gpa); + defer buffer.deinit(); + + for (self.thunks.items) |th| { + const thunk_size = th.size(self); + try buffer.ensureUnusedCapacity(thunk_size); + const shdr = self.shdrs.items[th.output_section_index]; + const offset = th.value + shdr.sh_offset; + try th.write(self, buffer.writer()); + assert(buffer.items.len == thunk_size); + try self.base.file.?.pwriteAll(buffer.items, offset); + buffer.clearRetainingCapacity(); + } + } + try self.reportUndefinedSymbols(&undefs); if (has_reloc_errors) return error.FlushFailure; @@ -4593,12 +4609,12 @@ pub fn updateSymtabSize(self: *Elf) !void { nlocals += 1; } - for (self.thunks.items) |*th| { + if (self.requiresThunks()) for (self.thunks.items) |*th| { th.output_symtab_ctx.ilocal = nlocals + 1; th.calcSymtabSize(self); nlocals += th.output_symtab_ctx.nlocals; strsize += th.output_symtab_ctx.strsize; - } + }; for (files.items) |index| { const file_ptr = self.file(index).?; @@ -4830,9 +4846,9 @@ pub fn writeSymtab(self: *Elf) !void { self.writeSectionSymbols(); - for (self.thunks.items) |th| { + if (self.requiresThunks()) for (self.thunks.items) |th| { th.writeSymtab(self); - } + }; if (self.zigObjectPtr()) |zig_object| { zig_object.asFile().writeSymtab(self); @@ -5997,10 +6013,14 @@ fn fmtDumpState( try writer.print("linker_defined({d}) : (linker defined)\n", .{index}); try writer.print("{}\n", .{linker_defined.fmtSymtab(self)}); } - try writer.writeAll("thunks\n"); - for (self.thunks.items, 0..) |th, index| { - try writer.print("thunk({d}) : {}\n", .{ index, th.fmt(self) }); + + if (self.requiresThunks()) { + try writer.writeAll("thunks\n"); + for (self.thunks.items, 0..) |th, index| { + try writer.print("thunk({d}) : {}\n", .{ index, th.fmt(self) }); + } } + try writer.print("{}\n", .{self.zig_got.fmt(self)}); try writer.print("{}\n", .{self.got.fmt(self)}); try writer.print("{}\n", .{self.plt.fmt(self)}); diff --git a/src/link/Elf/thunks.zig b/src/link/Elf/thunks.zig index 398a2acd93..119529b512 100644 --- a/src/link/Elf/thunks.zig +++ b/src/link/Elf/thunks.zig @@ -1,6 +1,7 @@ pub fn createThunks(shndx: u32, elf_file: *Elf) !void { const gpa = elf_file.base.comp.gpa; const cpu_arch = elf_file.getTarget().cpu.arch; + const max_distance = maxAllowedDistance(cpu_arch); const shdr = &elf_file.shdrs.items[shndx]; const atoms = elf_file.output_sections.get(shndx).?.items; assert(atoms.len > 0); @@ -17,12 +18,11 @@ pub fn createThunks(shndx: u32, elf_file: *Elf) !void { start_atom.value = try advance(shdr, start_atom.size, start_atom.alignment); i += 1; - while (i < atoms.len and - shdr.sh_size - start_atom.value < maxAllowedDistance(cpu_arch)) : (i += 1) - { + while (i < atoms.len) : (i += 1) { const atom_index = atoms[i]; const atom = elf_file.atom(atom_index).?; assert(atom.flags.alive); + if (atom.alignment.forward(shdr.sh_size) - start_atom.value >= max_distance) break; atom.value = try advance(shdr, atom.size, atom.alignment); } @@ -103,7 +103,7 @@ pub const Thunk = struct { } pub fn write(thunk: Thunk, elf_file: *Elf, writer: anytype) !void { - switch (elf_file.options.cpu_arch.?) { + switch (elf_file.getTarget().cpu.arch) { .aarch64 => try aarch64.write(thunk, elf_file, writer), .x86_64, .riscv64 => unreachable, else => @panic("unhandled arch"), |
