diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-30 15:11:10 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-09-04 13:34:25 +0200 |
| commit | 3e100c5daba0f64695eab0bb4216b9d242229ba6 (patch) | |
| tree | eb9e1be7edf581852d9740b9c405c2aac0e2df2b /src | |
| parent | da60159d85f2b23e35b62f0626163d798413916f (diff) | |
| download | zig-3e100c5daba0f64695eab0bb4216b9d242229ba6.tar.gz zig-3e100c5daba0f64695eab0bb4216b9d242229ba6.zip | |
dwarf: make Section.off a function
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/Dwarf.zig | 63 | ||||
| -rw-r--r-- | src/link/Elf.zig | 2 | ||||
| -rw-r--r-- | src/link/Elf/Atom.zig | 25 | ||||
| -rw-r--r-- | src/link/Elf/ZigObject.zig | 15 |
4 files changed, 56 insertions, 49 deletions
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 332c79e0fc..97bc15ced8 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -261,7 +261,6 @@ pub const Section = struct { index: u32, first: Unit.Index.Optional, last: Unit.Index.Optional, - off: u64, len: u64, units: std.ArrayListUnmanaged(Unit), @@ -284,9 +283,8 @@ pub const Section = struct { .index = std.math.maxInt(u32), .first = .none, .last = .none, - .off = 0, - .len = 0, .units = .{}, + .len = 0, }; fn deinit(sec: *Section, gpa: std.mem.Allocator) void { @@ -295,6 +293,20 @@ pub const Section = struct { sec.* = undefined; } + fn off(sec: Section, dwarf: *Dwarf) u64 { + if (dwarf.bin_file.cast(.elf)) |elf_file| { + const zo = elf_file.zigObjectPtr().?; + const atom = zo.symbol(sec.index).atom(elf_file).?; + return atom.offset(elf_file); + } else if (dwarf.bin_file.cast(.macho)) |macho_file| { + const header = if (macho_file.d_sym) |d_sym| + d_sym.sections.items[sec.index] + else + macho_file.sections.items(.header)[sec.index]; + return header.offset; + } else unreachable; + } + fn addUnit(sec: *Section, header_len: u32, trailer_len: u32, dwarf: *Dwarf) UpdateError!Unit.Index { const unit: Unit.Index = @enumFromInt(sec.units.items.len); const unit_ptr = try sec.units.addOne(dwarf.gpa); @@ -306,9 +318,9 @@ pub const Section = struct { .next = .none, .first = .none, .last = .none, - .off = 0, .header_len = aligned_header_len, .trailer_len = aligned_trailer_len, + .off = 0, .len = aligned_header_len + aligned_trailer_len, .entries = .{}, .cross_unit_relocs = .{}, @@ -385,7 +397,6 @@ pub const Section = struct { const shdr = elf_file.sections.items(.shdr)[shndx]; atom.size = shdr.sh_size; atom.alignment = InternPool.Alignment.fromNonzeroByteUnits(shdr.sh_addralign); - sec.off = shdr.sh_offset + @as(u64, @intCast(atom.value)); sec.len = shdr.sh_size; } else if (dwarf.bin_file.cast(.macho)) |macho_file| { const header = if (macho_file.d_sym) |*d_sym| header: { @@ -395,7 +406,6 @@ pub const Section = struct { try macho_file.growSection(@intCast(sec.index), len); break :header &macho_file.sections.items(.header)[sec.index]; }; - sec.off = header.offset; sec.len = header.size; } } @@ -404,7 +414,6 @@ pub const Section = struct { const len = sec.getUnit(sec.first.unwrap() orelse return).off; if (len == 0) return; for (sec.units.items) |*unit| unit.off -= len; - sec.off += len; sec.len -= len; if (dwarf.bin_file.cast(.elf)) |elf_file| { const zo = elf_file.zigObjectPtr().?; @@ -412,14 +421,14 @@ pub const Section = struct { const shndx = atom.output_section_index; const shdr = &elf_file.sections.items(.shdr)[shndx]; atom.size = sec.len; - shdr.sh_offset = sec.off; + shdr.sh_offset += len; shdr.sh_size = sec.len; } else if (dwarf.bin_file.cast(.macho)) |macho_file| { const header = if (macho_file.d_sym) |*d_sym| &d_sym.sections.items[sec.index] else &macho_file.sections.items(.header)[sec.index]; - header.offset = @intCast(sec.off); + header.offset += @intCast(len); header.size = sec.len; } } @@ -548,9 +557,9 @@ const Unit = struct { fn move(unit: *Unit, sec: *Section, dwarf: *Dwarf, new_off: u32) UpdateError!void { if (unit.off == new_off) return; if (try dwarf.getFile().?.copyRangeAll( - sec.off + unit.off, + sec.off(dwarf) + unit.off, dwarf.getFile().?, - sec.off + new_off, + sec.off(dwarf) + new_off, unit.len, ) != unit.len) return error.InputOutput; unit.off = new_off; @@ -582,7 +591,7 @@ const Unit = struct { fn replaceHeader(unit: *Unit, sec: *Section, dwarf: *Dwarf, contents: []const u8) UpdateError!void { assert(contents.len == unit.header_len); - try dwarf.getFile().?.pwriteAll(contents, sec.off + unit.off); + try dwarf.getFile().?.pwriteAll(contents, sec.off(dwarf) + unit.off); } fn writeTrailer(unit: *Unit, sec: *Section, dwarf: *Dwarf) UpdateError!void { @@ -614,7 +623,7 @@ const Unit = struct { assert(fbs.pos == extended_op_bytes + op_len_bytes); writer.writeByte(DW.LNE.padding) catch unreachable; assert(fbs.pos >= unit.trailer_len and fbs.pos <= len); - return dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off + start); + return dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off(dwarf) + start); } var trailer = try std.ArrayList(u8).initCapacity(dwarf.gpa, len); defer trailer.deinit(); @@ -673,11 +682,11 @@ const Unit = struct { assert(trailer.items.len == unit.trailer_len); trailer.appendNTimesAssumeCapacity(fill_byte, len - unit.trailer_len); assert(trailer.items.len == len); - try dwarf.getFile().?.pwriteAll(trailer.items, sec.off + start); + try dwarf.getFile().?.pwriteAll(trailer.items, sec.off(dwarf) + start); } fn resolveRelocs(unit: *Unit, sec: *Section, dwarf: *Dwarf) RelocError!void { - const unit_off = sec.off + unit.off; + const unit_off = sec.off(dwarf) + unit.off; for (unit.cross_unit_relocs.items) |reloc| { const target_unit = sec.getUnit(reloc.target_unit); try dwarf.resolveReloc( @@ -764,12 +773,12 @@ const Entry = struct { dwarf.writeInt(unit_len[0..dwarf.sectionOffsetBytes()], len - dwarf.unitLengthBytes()); try dwarf.getFile().?.pwriteAll( unit_len[0..dwarf.sectionOffsetBytes()], - sec.off + unit.off + unit.header_len + entry.off, + sec.off(dwarf) + unit.off + unit.header_len + entry.off, ); const buf = try dwarf.gpa.alloc(u8, len - entry.len); defer dwarf.gpa.free(buf); @memset(buf, DW.CFA.nop); - try dwarf.getFile().?.pwriteAll(buf, sec.off + unit.off + unit.header_len + start); + try dwarf.getFile().?.pwriteAll(buf, sec.off(dwarf) + unit.off + unit.header_len + start); return; } const len = unit.getEntry(entry.next.unwrap() orelse return).off - start; @@ -825,7 +834,7 @@ const Entry = struct { }, } else assert(!sec.pad_to_ideal and len == 0); assert(fbs.pos <= len); - try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off + unit.off + unit.header_len + start); + try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off(dwarf) + unit.off + unit.header_len + start); } fn resize(entry_ptr: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf, len: u32) UpdateError!void { @@ -860,15 +869,15 @@ const Entry = struct { fn replace(entry_ptr: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf, contents: []const u8) UpdateError!void { assert(contents.len == entry_ptr.len); - try dwarf.getFile().?.pwriteAll(contents, sec.off + unit.off + unit.header_len + entry_ptr.off); + try dwarf.getFile().?.pwriteAll(contents, sec.off(dwarf) + unit.off + unit.header_len + entry_ptr.off); if (false) { const buf = try dwarf.gpa.alloc(u8, sec.len); defer dwarf.gpa.free(buf); - _ = try dwarf.getFile().?.preadAll(buf, sec.off); + _ = try dwarf.getFile().?.preadAll(buf, sec.off(dwarf)); log.info("Section{{ .first = {}, .last = {}, .off = 0x{x}, .len = 0x{x} }}", .{ @intFromEnum(sec.first), @intFromEnum(sec.last), - sec.off, + sec.off(dwarf), sec.len, }); for (sec.units.items) |*unit_ptr| { @@ -935,7 +944,7 @@ const Entry = struct { } fn resolveRelocs(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) RelocError!void { - const entry_off = sec.off + unit.off + unit.header_len + entry.off; + const entry_off = sec.off(dwarf) + unit.off + unit.header_len + entry.off; for (entry.cross_entry_relocs.items) |reloc| { try dwarf.resolveReloc( entry_off + reloc.source_off, @@ -973,7 +982,7 @@ const Entry = struct { .eh_frame => return if (dwarf.bin_file.cast(.elf)) |elf_file| { const zo = elf_file.zigObjectPtr().?; const shndx = zo.symbol(sec.index).atom(elf_file).?.output_section_index; - const entry_addr: i64 = @intCast(entry_off - sec.off + elf_file.shdrs.items[shndx].sh_addr); + const entry_addr: i64 = @intCast(entry_off - sec.off(dwarf) + elf_file.shdrs.items[shndx].sh_addr); for (entry.external_relocs.items) |reloc| { const symbol = zo.symbol(reloc.target_sym); try dwarf.resolveReloc( @@ -1912,7 +1921,6 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void { }) |sec, sect_index| { const header = &d_sym.sections.items[sect_index]; sec.index = sect_index; - sec.off = header.offset; sec.len = header.size; } } else { @@ -1937,7 +1945,6 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void { }) |sec, sect_index| { const header = &macho_file.sections.items(.header)[sect_index]; sec.index = sect_index; - sec.off = header.offset; sec.len = header.size; } } @@ -2534,7 +2541,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined; if (try dwarf.getFile().?.preadAll( &abbrev_code_buf, - dwarf.debug_info.section.off + unit_ptr.off + unit_ptr.header_len + entry_ptr.off, + dwarf.debug_info.section.off(dwarf) + unit_ptr.off + unit_ptr.header_len + entry_ptr.off, ) != abbrev_code_buf.len) return error.InputOutput; var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf); const abbrev_code: AbbrevCode = @enumFromInt( @@ -3945,7 +3952,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { if (dwarf.debug_str.section.dirty) { const contents = dwarf.debug_str.contents.items; try dwarf.debug_str.section.resize(dwarf, contents.len); - try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_str.section.off); + try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_str.section.off(dwarf)); dwarf.debug_str.section.dirty = false; } if (dwarf.debug_line.section.dirty) { @@ -4051,7 +4058,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { if (dwarf.debug_line_str.section.dirty) { const contents = dwarf.debug_line_str.contents.items; try dwarf.debug_line_str.section.resize(dwarf, contents.len); - try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_line_str.section.off); + try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_line_str.section.off(dwarf)); dwarf.debug_line_str.section.dirty = false; } if (dwarf.debug_loclists.section.dirty) { diff --git a/src/link/Elf.zig b/src/link/Elf.zig index 2940759009..f182a4a868 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1070,7 +1070,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod if (shdr.sh_type == elf.SHT_NOBITS) continue; const code = try zo.codeAlloc(self, atom_index); defer gpa.free(code); - const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); + const file_offset = atom_ptr.offset(self); atom_ptr.resolveRelocsAlloc(self, code) catch |err| switch (err) { error.RelocFailure, error.RelaxFailure => has_reloc_errors = true, error.UnsupportedCpuArch => { diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 3d1fe04fb5..ab0e98440b 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -51,6 +51,11 @@ pub fn address(self: Atom, elf_file: *Elf) i64 { return @as(i64, @intCast(shdr.sh_addr)) + self.value; } +pub fn offset(self: Atom, elf_file: *Elf) u64 { + const shdr = elf_file.sections.items(.shdr)[self.output_section_index]; + return shdr.sh_offset + @as(u64, @intCast(self.value)); +} + pub fn ref(self: Atom) Elf.Ref { return .{ .index = self.atom_index, .file = self.file_index }; } @@ -1673,7 +1678,7 @@ const aarch64 = struct { => { // TODO: NC means no overflow check const taddr = @as(u64, @intCast(S + A)); - const offset: u12 = switch (r_type) { + const off: u12 = switch (r_type) { .LDST8_ABS_LO12_NC => @truncate(taddr), .LDST16_ABS_LO12_NC => @divExact(@as(u12, @truncate(taddr)), 2), .LDST32_ABS_LO12_NC => @divExact(@as(u12, @truncate(taddr)), 4), @@ -1681,7 +1686,7 @@ const aarch64 = struct { .LDST128_ABS_LO12_NC => @divExact(@as(u12, @truncate(taddr)), 16), else => unreachable, }; - aarch64_util.writeLoadStoreRegInst(offset, code); + aarch64_util.writeLoadStoreRegInst(off, code); }, .TLSLE_ADD_TPREL_HI12 => { @@ -1705,8 +1710,8 @@ const aarch64 = struct { .TLSIE_LD64_GOTTPREL_LO12_NC => { const S_ = target.gotTpAddress(elf_file); relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A }); - const offset: u12 = try math.divExact(u12, @truncate(@as(u64, @bitCast(S_ + A))), 8); - aarch64_util.writeLoadStoreRegInst(offset, code); + const off: u12 = try math.divExact(u12, @truncate(@as(u64, @bitCast(S_ + A))), 8); + aarch64_util.writeLoadStoreRegInst(off, code); }, .TLSGD_ADR_PAGE21 => { @@ -1719,8 +1724,8 @@ const aarch64 = struct { .TLSGD_ADD_LO12_NC => { const S_ = target.tlsGdAddress(elf_file); relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A }); - const offset: u12 = @truncate(@as(u64, @bitCast(S_ + A))); - aarch64_util.writeAddImmInst(offset, code); + const off: u12 = @truncate(@as(u64, @bitCast(S_ + A))); + aarch64_util.writeAddImmInst(off, code); }, .TLSDESC_ADR_PAGE21 => { @@ -1739,8 +1744,8 @@ const aarch64 = struct { if (target.flags.has_tlsdesc) { const S_ = target.tlsDescAddress(elf_file); relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A }); - const offset: u12 = try math.divExact(u12, @truncate(@as(u64, @bitCast(S_ + A))), 8); - aarch64_util.writeLoadStoreRegInst(offset, code); + const off: u12 = try math.divExact(u12, @truncate(@as(u64, @bitCast(S_ + A))), 8); + aarch64_util.writeLoadStoreRegInst(off, code); } else { relocs_log.debug(" relaxing ldr => nop", .{}); mem.writeInt(u32, code, Instruction.nop().toU32(), .little); @@ -1751,8 +1756,8 @@ const aarch64 = struct { if (target.flags.has_tlsdesc) { const S_ = target.tlsDescAddress(elf_file); relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A }); - const offset: u12 = @truncate(@as(u64, @bitCast(S_ + A))); - aarch64_util.writeAddImmInst(offset, code); + const off: u12 = @truncate(@as(u64, @bitCast(S_ + A))); + aarch64_util.writeAddImmInst(off, code); } else { const old_inst = Instruction{ .add_subtract_immediate = mem.bytesToValue(std.meta.TagPayload( diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 8de8551463..8f16672591 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -906,7 +906,7 @@ pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 return code; } - const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); + const file_offset = atom_ptr.offset(elf_file); const size = std.math.cast(usize, atom_ptr.size) orelse return error.Overflow; const code = try gpa.alloc(u8, size); errdefer gpa.free(code); @@ -1338,7 +1338,7 @@ fn updateNavCode( const shdr = elf_file.sections.items(.shdr)[shdr_index]; if (shdr.sh_type != elf.SHT_NOBITS) { - const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); + const file_offset = atom_ptr.offset(elf_file); 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 }); } @@ -1716,9 +1716,7 @@ fn updateLazySymbol( local_sym.value = 0; local_esym.st_value = 0; - const shdr = elf_file.sections.items(.shdr)[output_section_index]; - const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); - try elf_file.base.file.?.pwriteAll(code, file_offset); + try elf_file.base.file.?.pwriteAll(code, atom_ptr.offset(elf_file)); } const LowerConstResult = union(enum) { @@ -1771,9 +1769,7 @@ fn lowerConst( try self.allocateAtom(atom_ptr, elf_file); errdefer self.freeNavMetadata(elf_file, sym_index); - const shdr = elf_file.sections.items(.shdr)[output_section_index]; - const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); - try elf_file.base.file.?.pwriteAll(code, file_offset); + try elf_file.base.file.?.pwriteAll(code, atom_ptr.offset(elf_file)); return .{ .ok = sym_index }; } @@ -1935,8 +1931,7 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) u64 { fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void { const atom_ptr = tr_sym.atom(elf_file).?; - const shdr = elf_file.sections.items(.shdr)[atom_ptr.output_section_index]; - const fileoff = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); + const fileoff = atom_ptr.offset(elf_file); const source_addr = tr_sym.address(.{}, elf_file); const target_addr = target.address(.{ .trampoline = false }, elf_file); var buf: [max_trampoline_len]u8 = undefined; |
