authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-30 15:11:10+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-09-04 13:34:25+02:00
log3e100c5daba0f64695eab0bb4216b9d242229ba6
treeeb9e1be7edf581852d9740b9c405c2aac0e2df2b
parentda60159d85f2b23e35b62f0626163d798413916f

dwarf: make Section.off a function


4 files changed, 56 insertions(+), 49 deletions(-)

src/link/Dwarf.zig+35-28
......@@ -261,7 +261,6 @@ pub const Section = struct {
261261 index: u32,
262262 first: Unit.Index.Optional,
263263 last: Unit.Index.Optional,
264 off: u64,
265264 len: u64,
266265 units: std.ArrayListUnmanaged(Unit),
267266
......@@ -284,9 +283,8 @@ pub const Section = struct {
284283 .index = std.math.maxInt(u32),
285284 .first = .none,
286285 .last = .none,
287 .off = 0,
288 .len = 0,
289286 .units = .{},
287 .len = 0,
290288 };
291289
292290 fn deinit(sec: *Section, gpa: std.mem.Allocator) void {
......@@ -295,6 +293,20 @@ pub const Section = struct {
295293 sec.* = undefined;
296294 }
297295
296 fn off(sec: Section, dwarf: *Dwarf) u64 {
297 if (dwarf.bin_file.cast(.elf)) |elf_file| {
298 const zo = elf_file.zigObjectPtr().?;
299 const atom = zo.symbol(sec.index).atom(elf_file).?;
300 return atom.offset(elf_file);
301 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {
302 const header = if (macho_file.d_sym) |d_sym|
303 d_sym.sections.items[sec.index]
304 else
305 macho_file.sections.items(.header)[sec.index];
306 return header.offset;
307 } else unreachable;
308 }
309
298310 fn addUnit(sec: *Section, header_len: u32, trailer_len: u32, dwarf: *Dwarf) UpdateError!Unit.Index {
299311 const unit: Unit.Index = @enumFromInt(sec.units.items.len);
300312 const unit_ptr = try sec.units.addOne(dwarf.gpa);
......@@ -306,9 +318,9 @@ pub const Section = struct {
306318 .next = .none,
307319 .first = .none,
308320 .last = .none,
309 .off = 0,
310321 .header_len = aligned_header_len,
311322 .trailer_len = aligned_trailer_len,
323 .off = 0,
312324 .len = aligned_header_len + aligned_trailer_len,
313325 .entries = .{},
314326 .cross_unit_relocs = .{},
......@@ -385,7 +397,6 @@ pub const Section = struct {
385397 const shdr = elf_file.sections.items(.shdr)[shndx];
386398 atom.size = shdr.sh_size;
387399 atom.alignment = InternPool.Alignment.fromNonzeroByteUnits(shdr.sh_addralign);
388 sec.off = shdr.sh_offset + @as(u64, @intCast(atom.value));
389400 sec.len = shdr.sh_size;
390401 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {
391402 const header = if (macho_file.d_sym) |*d_sym| header: {
......@@ -395,7 +406,6 @@ pub const Section = struct {
395406 try macho_file.growSection(@intCast(sec.index), len);
396407 break :header &macho_file.sections.items(.header)[sec.index];
397408 };
398 sec.off = header.offset;
399409 sec.len = header.size;
400410 }
401411 }
......@@ -404,7 +414,6 @@ pub const Section = struct {
404414 const len = sec.getUnit(sec.first.unwrap() orelse return).off;
405415 if (len == 0) return;
406416 for (sec.units.items) |*unit| unit.off -= len;
407 sec.off += len;
408417 sec.len -= len;
409418 if (dwarf.bin_file.cast(.elf)) |elf_file| {
410419 const zo = elf_file.zigObjectPtr().?;
......@@ -412,14 +421,14 @@ pub const Section = struct {
412421 const shndx = atom.output_section_index;
413422 const shdr = &elf_file.sections.items(.shdr)[shndx];
414423 atom.size = sec.len;
415 shdr.sh_offset = sec.off;
424 shdr.sh_offset += len;
416425 shdr.sh_size = sec.len;
417426 } else if (dwarf.bin_file.cast(.macho)) |macho_file| {
418427 const header = if (macho_file.d_sym) |*d_sym|
419428 &d_sym.sections.items[sec.index]
420429 else
421430 &macho_file.sections.items(.header)[sec.index];
422 header.offset = @intCast(sec.off);
431 header.offset += @intCast(len);
423432 header.size = sec.len;
424433 }
425434 }
......@@ -548,9 +557,9 @@ const Unit = struct {
548557 fn move(unit: *Unit, sec: *Section, dwarf: *Dwarf, new_off: u32) UpdateError!void {
549558 if (unit.off == new_off) return;
550559 if (try dwarf.getFile().?.copyRangeAll(
551 sec.off + unit.off,
560 sec.off(dwarf) + unit.off,
552561 dwarf.getFile().?,
553 sec.off + new_off,
562 sec.off(dwarf) + new_off,
554563 unit.len,
555564 ) != unit.len) return error.InputOutput;
556565 unit.off = new_off;
......@@ -582,7 +591,7 @@ const Unit = struct {
582591
583592 fn replaceHeader(unit: *Unit, sec: *Section, dwarf: *Dwarf, contents: []const u8) UpdateError!void {
584593 assert(contents.len == unit.header_len);
585 try dwarf.getFile().?.pwriteAll(contents, sec.off + unit.off);
594 try dwarf.getFile().?.pwriteAll(contents, sec.off(dwarf) + unit.off);
586595 }
587596
588597 fn writeTrailer(unit: *Unit, sec: *Section, dwarf: *Dwarf) UpdateError!void {
......@@ -614,7 +623,7 @@ const Unit = struct {
614623 assert(fbs.pos == extended_op_bytes + op_len_bytes);
615624 writer.writeByte(DW.LNE.padding) catch unreachable;
616625 assert(fbs.pos >= unit.trailer_len and fbs.pos <= len);
617 return dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off + start);
626 return dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off(dwarf) + start);
618627 }
619628 var trailer = try std.ArrayList(u8).initCapacity(dwarf.gpa, len);
620629 defer trailer.deinit();
......@@ -673,11 +682,11 @@ const Unit = struct {
673682 assert(trailer.items.len == unit.trailer_len);
674683 trailer.appendNTimesAssumeCapacity(fill_byte, len - unit.trailer_len);
675684 assert(trailer.items.len == len);
676 try dwarf.getFile().?.pwriteAll(trailer.items, sec.off + start);
685 try dwarf.getFile().?.pwriteAll(trailer.items, sec.off(dwarf) + start);
677686 }
678687
679688 fn resolveRelocs(unit: *Unit, sec: *Section, dwarf: *Dwarf) RelocError!void {
680 const unit_off = sec.off + unit.off;
689 const unit_off = sec.off(dwarf) + unit.off;
681690 for (unit.cross_unit_relocs.items) |reloc| {
682691 const target_unit = sec.getUnit(reloc.target_unit);
683692 try dwarf.resolveReloc(
......@@ -764,12 +773,12 @@ const Entry = struct {
764773 dwarf.writeInt(unit_len[0..dwarf.sectionOffsetBytes()], len - dwarf.unitLengthBytes());
765774 try dwarf.getFile().?.pwriteAll(
766775 unit_len[0..dwarf.sectionOffsetBytes()],
767 sec.off + unit.off + unit.header_len + entry.off,
776 sec.off(dwarf) + unit.off + unit.header_len + entry.off,
768777 );
769778 const buf = try dwarf.gpa.alloc(u8, len - entry.len);
770779 defer dwarf.gpa.free(buf);
771780 @memset(buf, DW.CFA.nop);
772 try dwarf.getFile().?.pwriteAll(buf, sec.off + unit.off + unit.header_len + start);
781 try dwarf.getFile().?.pwriteAll(buf, sec.off(dwarf) + unit.off + unit.header_len + start);
773782 return;
774783 }
775784 const len = unit.getEntry(entry.next.unwrap() orelse return).off - start;
......@@ -825,7 +834,7 @@ const Entry = struct {
825834 },
826835 } else assert(!sec.pad_to_ideal and len == 0);
827836 assert(fbs.pos <= len);
828 try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off + unit.off + unit.header_len + start);
837 try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off(dwarf) + unit.off + unit.header_len + start);
829838 }
830839
831840 fn resize(entry_ptr: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf, len: u32) UpdateError!void {
......@@ -860,15 +869,15 @@ const Entry = struct {
860869
861870 fn replace(entry_ptr: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf, contents: []const u8) UpdateError!void {
862871 assert(contents.len == entry_ptr.len);
863 try dwarf.getFile().?.pwriteAll(contents, sec.off + unit.off + unit.header_len + entry_ptr.off);
872 try dwarf.getFile().?.pwriteAll(contents, sec.off(dwarf) + unit.off + unit.header_len + entry_ptr.off);
864873 if (false) {
865874 const buf = try dwarf.gpa.alloc(u8, sec.len);
866875 defer dwarf.gpa.free(buf);
867 _ = try dwarf.getFile().?.preadAll(buf, sec.off);
876 _ = try dwarf.getFile().?.preadAll(buf, sec.off(dwarf));
868877 log.info("Section{{ .first = {}, .last = {}, .off = 0x{x}, .len = 0x{x} }}", .{
869878 @intFromEnum(sec.first),
870879 @intFromEnum(sec.last),
871 sec.off,
880 sec.off(dwarf),
872881 sec.len,
873882 });
874883 for (sec.units.items) |*unit_ptr| {
......@@ -935,7 +944,7 @@ const Entry = struct {
935944 }
936945
937946 fn resolveRelocs(entry: *Entry, unit: *Unit, sec: *Section, dwarf: *Dwarf) RelocError!void {
938 const entry_off = sec.off + unit.off + unit.header_len + entry.off;
947 const entry_off = sec.off(dwarf) + unit.off + unit.header_len + entry.off;
939948 for (entry.cross_entry_relocs.items) |reloc| {
940949 try dwarf.resolveReloc(
941950 entry_off + reloc.source_off,
......@@ -973,7 +982,7 @@ const Entry = struct {
973982 .eh_frame => return if (dwarf.bin_file.cast(.elf)) |elf_file| {
974983 const zo = elf_file.zigObjectPtr().?;
975984 const shndx = zo.symbol(sec.index).atom(elf_file).?.output_section_index;
976 const entry_addr: i64 = @intCast(entry_off - sec.off + elf_file.shdrs.items[shndx].sh_addr);
985 const entry_addr: i64 = @intCast(entry_off - sec.off(dwarf) + elf_file.shdrs.items[shndx].sh_addr);
977986 for (entry.external_relocs.items) |reloc| {
978987 const symbol = zo.symbol(reloc.target_sym);
979988 try dwarf.resolveReloc(
......@@ -1912,7 +1921,6 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void {
19121921 }) |sec, sect_index| {
19131922 const header = &d_sym.sections.items[sect_index];
19141923 sec.index = sect_index;
1915 sec.off = header.offset;
19161924 sec.len = header.size;
19171925 }
19181926 } else {
......@@ -1937,7 +1945,6 @@ pub fn reloadSectionMetadata(dwarf: *Dwarf) void {
19371945 }) |sec, sect_index| {
19381946 const header = &macho_file.sections.items(.header)[sect_index];
19391947 sec.index = sect_index;
1940 sec.off = header.offset;
19411948 sec.len = header.size;
19421949 }
19431950 }
......@@ -2534,7 +2541,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
25342541 var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined;
25352542 if (try dwarf.getFile().?.preadAll(
25362543 &abbrev_code_buf,
2537 dwarf.debug_info.section.off + unit_ptr.off + unit_ptr.header_len + entry_ptr.off,
2544 dwarf.debug_info.section.off(dwarf) + unit_ptr.off + unit_ptr.header_len + entry_ptr.off,
25382545 ) != abbrev_code_buf.len) return error.InputOutput;
25392546 var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
25402547 const abbrev_code: AbbrevCode = @enumFromInt(
......@@ -3945,7 +3952,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
39453952 if (dwarf.debug_str.section.dirty) {
39463953 const contents = dwarf.debug_str.contents.items;
39473954 try dwarf.debug_str.section.resize(dwarf, contents.len);
3948 try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_str.section.off);
3955 try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_str.section.off(dwarf));
39493956 dwarf.debug_str.section.dirty = false;
39503957 }
39513958 if (dwarf.debug_line.section.dirty) {
......@@ -4051,7 +4058,7 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
40514058 if (dwarf.debug_line_str.section.dirty) {
40524059 const contents = dwarf.debug_line_str.contents.items;
40534060 try dwarf.debug_line_str.section.resize(dwarf, contents.len);
4054 try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_line_str.section.off);
4061 try dwarf.getFile().?.pwriteAll(contents, dwarf.debug_line_str.section.off(dwarf));
40554062 dwarf.debug_line_str.section.dirty = false;
40564063 }
40574064 if (dwarf.debug_loclists.section.dirty) {
src/link/Elf.zig+1-1
......@@ -1070,7 +1070,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
10701070 if (shdr.sh_type == elf.SHT_NOBITS) continue;
10711071 const code = try zo.codeAlloc(self, atom_index);
10721072 defer gpa.free(code);
1073 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
1073 const file_offset = atom_ptr.offset(self);
10741074 atom_ptr.resolveRelocsAlloc(self, code) catch |err| switch (err) {
10751075 error.RelocFailure, error.RelaxFailure => has_reloc_errors = true,
10761076 error.UnsupportedCpuArch => {
src/link/Elf/Atom.zig+15-10
......@@ -51,6 +51,11 @@ pub fn address(self: Atom, elf_file: *Elf) i64 {
5151 return @as(i64, @intCast(shdr.sh_addr)) + self.value;
5252}
5353
54pub fn offset(self: Atom, elf_file: *Elf) u64 {
55 const shdr = elf_file.sections.items(.shdr)[self.output_section_index];
56 return shdr.sh_offset + @as(u64, @intCast(self.value));
57}
58
5459pub fn ref(self: Atom) Elf.Ref {
5560 return .{ .index = self.atom_index, .file = self.file_index };
5661}
......@@ -1673,7 +1678,7 @@ const aarch64 = struct {
16731678 => {
16741679 // TODO: NC means no overflow check
16751680 const taddr = @as(u64, @intCast(S + A));
1676 const offset: u12 = switch (r_type) {
1681 const off: u12 = switch (r_type) {
16771682 .LDST8_ABS_LO12_NC => @truncate(taddr),
16781683 .LDST16_ABS_LO12_NC => @divExact(@as(u12, @truncate(taddr)), 2),
16791684 .LDST32_ABS_LO12_NC => @divExact(@as(u12, @truncate(taddr)), 4),
......@@ -1681,7 +1686,7 @@ const aarch64 = struct {
16811686 .LDST128_ABS_LO12_NC => @divExact(@as(u12, @truncate(taddr)), 16),
16821687 else => unreachable,
16831688 };
1684 aarch64_util.writeLoadStoreRegInst(offset, code);
1689 aarch64_util.writeLoadStoreRegInst(off, code);
16851690 },
16861691
16871692 .TLSLE_ADD_TPREL_HI12 => {
......@@ -1705,8 +1710,8 @@ const aarch64 = struct {
17051710 .TLSIE_LD64_GOTTPREL_LO12_NC => {
17061711 const S_ = target.gotTpAddress(elf_file);
17071712 relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
1708 const offset: u12 = try math.divExact(u12, @truncate(@as(u64, @bitCast(S_ + A))), 8);
1709 aarch64_util.writeLoadStoreRegInst(offset, code);
1713 const off: u12 = try math.divExact(u12, @truncate(@as(u64, @bitCast(S_ + A))), 8);
1714 aarch64_util.writeLoadStoreRegInst(off, code);
17101715 },
17111716
17121717 .TLSGD_ADR_PAGE21 => {
......@@ -1719,8 +1724,8 @@ const aarch64 = struct {
17191724 .TLSGD_ADD_LO12_NC => {
17201725 const S_ = target.tlsGdAddress(elf_file);
17211726 relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
1722 const offset: u12 = @truncate(@as(u64, @bitCast(S_ + A)));
1723 aarch64_util.writeAddImmInst(offset, code);
1727 const off: u12 = @truncate(@as(u64, @bitCast(S_ + A)));
1728 aarch64_util.writeAddImmInst(off, code);
17241729 },
17251730
17261731 .TLSDESC_ADR_PAGE21 => {
......@@ -1739,8 +1744,8 @@ const aarch64 = struct {
17391744 if (target.flags.has_tlsdesc) {
17401745 const S_ = target.tlsDescAddress(elf_file);
17411746 relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
1742 const offset: u12 = try math.divExact(u12, @truncate(@as(u64, @bitCast(S_ + A))), 8);
1743 aarch64_util.writeLoadStoreRegInst(offset, code);
1747 const off: u12 = try math.divExact(u12, @truncate(@as(u64, @bitCast(S_ + A))), 8);
1748 aarch64_util.writeLoadStoreRegInst(off, code);
17441749 } else {
17451750 relocs_log.debug(" relaxing ldr => nop", .{});
17461751 mem.writeInt(u32, code, Instruction.nop().toU32(), .little);
......@@ -1751,8 +1756,8 @@ const aarch64 = struct {
17511756 if (target.flags.has_tlsdesc) {
17521757 const S_ = target.tlsDescAddress(elf_file);
17531758 relocs_log.debug(" [{x} => {x}]", .{ P, S_ + A });
1754 const offset: u12 = @truncate(@as(u64, @bitCast(S_ + A)));
1755 aarch64_util.writeAddImmInst(offset, code);
1759 const off: u12 = @truncate(@as(u64, @bitCast(S_ + A)));
1760 aarch64_util.writeAddImmInst(off, code);
17561761 } else {
17571762 const old_inst = Instruction{
17581763 .add_subtract_immediate = mem.bytesToValue(std.meta.TagPayload(
src/link/Elf/ZigObject.zig+5-10
......@@ -906,7 +906,7 @@ pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8
906906 return code;
907907 }
908908
909 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
909 const file_offset = atom_ptr.offset(elf_file);
910910 const size = std.math.cast(usize, atom_ptr.size) orelse return error.Overflow;
911911 const code = try gpa.alloc(u8, size);
912912 errdefer gpa.free(code);
......@@ -1338,7 +1338,7 @@ fn updateNavCode(
13381338
13391339 const shdr = elf_file.sections.items(.shdr)[shdr_index];
13401340 if (shdr.sh_type != elf.SHT_NOBITS) {
1341 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
1341 const file_offset = atom_ptr.offset(elf_file);
13421342 try elf_file.base.file.?.pwriteAll(code, file_offset);
13431343 log.debug("writing {} from 0x{x} to 0x{x}", .{ nav.fqn.fmt(ip), file_offset, file_offset + code.len });
13441344 }
......@@ -1716,9 +1716,7 @@ fn updateLazySymbol(
17161716 local_sym.value = 0;
17171717 local_esym.st_value = 0;
17181718
1719 const shdr = elf_file.sections.items(.shdr)[output_section_index];
1720 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
1721 try elf_file.base.file.?.pwriteAll(code, file_offset);
1719 try elf_file.base.file.?.pwriteAll(code, atom_ptr.offset(elf_file));
17221720}
17231721
17241722const LowerConstResult = union(enum) {
......@@ -1771,9 +1769,7 @@ fn lowerConst(
17711769 try self.allocateAtom(atom_ptr, elf_file);
17721770 errdefer self.freeNavMetadata(elf_file, sym_index);
17731771
1774 const shdr = elf_file.sections.items(.shdr)[output_section_index];
1775 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
1776 try elf_file.base.file.?.pwriteAll(code, file_offset);
1772 try elf_file.base.file.?.pwriteAll(code, atom_ptr.offset(elf_file));
17771773
17781774 return .{ .ok = sym_index };
17791775}
......@@ -1935,8 +1931,7 @@ fn trampolineSize(cpu_arch: std.Target.Cpu.Arch) u64 {
19351931
19361932fn writeTrampoline(tr_sym: Symbol, target: Symbol, elf_file: *Elf) !void {
19371933 const atom_ptr = tr_sym.atom(elf_file).?;
1938 const shdr = elf_file.sections.items(.shdr)[atom_ptr.output_section_index];
1939 const fileoff = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
1934 const fileoff = atom_ptr.offset(elf_file);
19401935 const source_addr = tr_sym.address(.{}, elf_file);
19411936 const target_addr = target.address(.{ .trampoline = false }, elf_file);
19421937 var buf: [max_trampoline_len]u8 = undefined;