dwarf: make Section.off a function
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user