Commit 3e100c5dab
Changed files (4)
src
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(
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;
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) {
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 => {