diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-15 08:37:13 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-15 08:37:13 +0200 |
| commit | b8203fac1b272d4f13f668797cf356d995b7967f (patch) | |
| tree | 7334553f2a3460ffaa1a90aa76367aee7ca50919 /src/link | |
| parent | f26573fddfcebe44d4d69ea0e01d345fc1b15835 (diff) | |
| download | zig-b8203fac1b272d4f13f668797cf356d995b7967f.tar.gz zig-b8203fac1b272d4f13f668797cf356d995b7967f.zip | |
elf: check for relocs before deciding on shndx in getNavShdrIndex
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Elf.zig | 5 | ||||
| -rw-r--r-- | src/link/Elf/ZigObject.zig | 32 |
2 files changed, 28 insertions, 9 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 1c2f90d14c..3dcfb0bc6a 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -857,6 +857,11 @@ pub fn growAllocSection(self: *Elf, shdr_index: u32, needed_size: u64) !void { const shdr = &self.shdrs.items[shdr_index]; const maybe_phdr = if (self.phdr_to_shdr_table.get(shdr_index)) |phndx| &self.phdrs.items[phndx] else null; const is_zerofill = shdr.sh_type == elf.SHT_NOBITS; + log.debug("allocated size {x} of {s}, needed size {x}", .{ + self.allocatedSize(shdr.sh_offset), + self.getShString(shdr.sh_name), + needed_size, + }); if (needed_size > self.allocatedSize(shdr.sh_offset) and !is_zerofill) { const existing_size = shdr.sh_size; diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index a472c6fad0..4c05c0b985 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -816,9 +816,9 @@ fn getNavShdrIndex( elf_file: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index, + sym_index: Symbol.Index, code: []const u8, ) error{OutOfMemory}!u32 { - _ = self; const ip = &zcu.intern_pool; const any_non_single_threaded = elf_file.base.comp.config.any_non_single_threaded; const nav_val = zcu.navValue(nav_index); @@ -828,10 +828,12 @@ fn getNavShdrIndex( .@"extern" => |@"extern"| .{ @"extern".is_const, @"extern".is_threadlocal, .none }, else => .{ true, false, nav_val.toIntern() }, }; + const has_relocs = self.symbol(sym_index).atom(elf_file).?.relocs(elf_file).len > 0; if (any_non_single_threaded and is_threadlocal) { - for (code) |byte| { - if (byte != 0) break; - } else return elf_file.sectionByName(".tbss") orelse try elf_file.addSection(.{ + const is_bss = !has_relocs and for (code) |byte| { + if (byte != 0) break false; + } else true; + if (is_bss) return elf_file.sectionByName(".tbss") orelse try elf_file.addSection(.{ .type = elf.SHT_NOBITS, .flags = elf.SHF_ALLOC | elf.SHF_WRITE | elf.SHF_TLS, .name = try elf_file.insertShString(".tbss"), @@ -850,9 +852,10 @@ fn getNavShdrIndex( .Debug, .ReleaseSafe => elf_file.zig_data_section_index.?, .ReleaseFast, .ReleaseSmall => elf_file.zig_bss_section_index.?, }; - for (code) |byte| { - if (byte != 0) break; - } else return elf_file.zig_bss_section_index.?; + const is_bss = !has_relocs and for (code) |byte| { + if (byte != 0) break false; + } else true; + if (is_bss) return elf_file.zig_bss_section_index.?; return elf_file.zig_data_section_index.?; } @@ -944,6 +947,7 @@ fn updateNavCode( if (shdr.sh_type != elf.SHT_NOBITS) { const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); try elf_file.base.file.?.pwriteAll(code, file_offset); + log.debug("writing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), file_offset, file_offset + code.len }); } } @@ -1052,7 +1056,12 @@ pub fn updateFunc( }, }; - const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, code); + const shndx = try self.getNavShdrIndex(elf_file, zcu, func.owner_nav, sym_index, code); + log.debug("setting shdr({x},{s}) for {}", .{ + shndx, + elf_file.getShString(elf_file.shdrs.items[shndx].sh_name), + ip.getNav(func.owner_nav).fqn.fmt(ip), + }); const old_rva, const old_alignment = blk: { const atom_ptr = self.symbol(sym_index).atom(elf_file).?; break :blk .{ atom_ptr.value, atom_ptr.alignment }; @@ -1172,7 +1181,12 @@ pub fn updateNav( }, }; - const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, code); + const shndx = try self.getNavShdrIndex(elf_file, zcu, nav_index, sym_index, code); + log.debug("setting shdr({x},{s}) for {}", .{ + shndx, + elf_file.getShString(elf_file.shdrs.items[shndx].sh_name), + nav.fqn.fmt(ip), + }); if (elf_file.shdrs.items[shndx].sh_flags & elf.SHF_TLS != 0) try self.updateTlv(elf_file, pt, nav_index, sym_index, shndx, code) else |
