authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2026-06-23 22:05:25-04:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2026-06-23 22:05:25-04:00
logd94b3e7691f15b8bc6993cc6999d0f439255ed80
tree989a2e168ad321000989343a45ccafbab933def6
parentbe7b9dec521f36909643c7084c16c284968a7db3

Coff: fix incorrect section offset calculations when writing section relocation tables


2 files changed, 22 insertions(+), 11 deletions(-)

src/link/Coff.zig+21-10
......@@ -1110,7 +1110,7 @@ pub const Symbol = struct {
11101110 if (reloc.loc != si) break;
11111111 if (reloc.sri.entry(coff, sym.section_number)) |entry| coff.targetStore(
11121112 &entry.virtual_address,
1113 @intCast(coff.computeSymbolSectionOffset(sym) + reloc.offset),
1113 @intCast(coff.computeSymbolSectionOffset(sym, .image) + reloc.offset),
11141114 );
11151115 try reloc.apply(coff);
11161116 }
......@@ -1442,7 +1442,7 @@ pub const Reloc = extern struct {
14421442 .SECREL => std.mem.writeInt(
14431443 u32,
14441444 loc_slice[0..4],
1445 @intCast(coff.computeSymbolSectionOffset(target_sym) + reloc.addend),
1445 @intCast(coff.computeSymbolSectionOffset(target_sym, .pseudo) + reloc.addend),
14461446 target_endian,
14471447 ),
14481448 },
......@@ -1482,7 +1482,7 @@ pub const Reloc = extern struct {
14821482 .SECREL => std.mem.writeInt(
14831483 u32,
14841484 loc_slice[0..4],
1485 @intCast(coff.computeSymbolSectionOffset(target_sym) + reloc.addend),
1485 @intCast(coff.computeSymbolSectionOffset(target_sym, .pseudo) + reloc.addend),
14861486 target_endian,
14871487 ),
14881488 },
......@@ -1496,7 +1496,7 @@ pub const Reloc = extern struct {
14961496 // TODO: If this was the last reloc causing something to be in the symbol table, we should remove
14971497 // the symbol table entry (and unset sti). That will require flushSymbolTableIndex on the
14981498 // swapped symbol if we exchange indices
1499 unreachable;
1499 @panic("TODO implement symbol table reloc deletions");
15001500 }
15011501
15021502 switch (reloc.prev) {
......@@ -2443,7 +2443,12 @@ fn computeNodeRva(coff: *Coff, ni: MappedFile.Node.Index) u32 {
24432443 const offset, _ = ni.location(&coff.mf).resolve(&coff.mf);
24442444 return @intCast(parent_rva + offset);
24452445}
2446fn computeSymbolSectionOffset(coff: *Coff, sym: *const Symbol) u32 {
2446
2447fn computeSymbolSectionOffset(
2448 coff: *Coff,
2449 sym: *const Symbol,
2450 relative_to: enum { image, pseudo },
2451) u32 {
24472452 var section_offset: u32 = sym.nodeOffset(coff);
24482453 var parent_ni = sym.ni;
24492454 while (true) {
......@@ -2452,10 +2457,14 @@ fn computeSymbolSectionOffset(coff: *Coff, sym: *const Symbol) u32 {
24522457 parent_ni = parent_ni.parent(&coff.mf);
24532458 switch (coff.getNode(parent_ni)) {
24542459 else => unreachable,
2455 .image_section, .pseudo_section => return section_offset,
2456 .object_section => {},
2460 .image_section => break,
2461 .pseudo_section => if (relative_to == .pseudo) break,
2462 .object_section,
2463 => {},
24572464 }
24582465 }
2466
2467 return section_offset;
24592468}
24602469
24612470pub inline fn targetEndian(_: *const Coff) std.lang.Endian {
......@@ -3279,7 +3288,7 @@ fn flushSymbolTableEntry(coff: *Coff, index: u32, pt: Zcu.PerThread) !void {
32793288 => unreachable,
32803289 else => switch (coff.getNode(sym.ni)) {
32813290 .image_section => 0,
3282 else => coff.computeSymbolSectionOffset(sym),
3291 else => coff.computeSymbolSectionOffset(sym, .image),
32833292 },
32843293 });
32853294
......@@ -3328,10 +3337,12 @@ fn flushInputSection(coff: *Coff, isi: Node.InputSection.Index) !void {
33283337 const si = isi.symbol(coff);
33293338 si.node(coff).writer(&coff.mf, gpa, &nw);
33303339 defer nw.deinit();
3331 log.debug("flushInputSection({f}{f}, {s})", .{
3340 log.debug("flushInputSection({f}{f}, {s}, {d}, n{d})", .{
33323341 path,
33333342 fmtMemberNameString(ioi.memberName(coff)),
3334 isi.symbol(coff).get(coff).section_number.name(coff).toSlice(coff),
3343 si.get(coff).section_number.name(coff).toSlice(coff),
3344 si,
3345 si.node(coff),
33353346 });
33363347 if (try nw.interface.sendFileAll(&fr, .limited(@intCast(file_loc.size))) != file_loc.size)
33373348 return error.EndOfStream;
test/link/snapshots/.gitattributes+1-1
......@@ -1 +1 @@
1* -text
1*.dmp eol=lf