authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-10-16 16:09:46+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-10-16 17:41:24+01:00
log0d69f3a619d03c08f37837f18e35b3953a3bfe55
tree3953a3ddca8806582fcd2d17a18fd59592fcca72
parentfbeb341d9689959f222eefa8720c234e8a5ec9c7
signature Commit is signed but in an unrecognized format.

Elf2: minor cleanups


1 files changed, 48 insertions(+), 33 deletions(-)

src/link/Elf2.zig+48-33
......@@ -684,16 +684,18 @@ const Section = struct {
684684 }
685685 } else {
686686 // For sections without nodes (NOBITS), propagate alignment to the parent.
687 assert(switch (elf.shdrPtr(shndx)) {
688 inline else => |shdr| elf.targetLoad(&shdr.type) == .NOBITS,
689 });
687 switch (elf.shdrPtr(shndx)) {
688 inline else => |shdr| assert(elf.targetLoad(&shdr.type) == .NOBITS),
689 }
690690
691691 if (elf.ehdrType() == .REL) return;
692692
693 const segment_ni = if (shndx.flags(elf).TLS)
694 elf.ni.tls.unwrap().?
695 else
696 elf.ni.data;
693 const segment_ni: MappedFile.Node.Index = seg: {
694 if (shndx == elf.shndx.bss) break :seg elf.ni.data;
695 if (shndx == elf.shndx.tbss) break :seg elf.ni.tls.unwrap().?;
696 // NOBITS sections other than `.bss` and `.tbss` are only emitted in `ET_REL`s.
697 unreachable;
698 };
697699
698700 try elf.ensureSegmentAligned(elf.getNode(segment_ni).segment, min_align);
699701 }
......@@ -7052,7 +7054,11 @@ fn mapInputSection(elf: *Elf, opts: struct {
70527054 name: []const u8,
70537055 flags: std.elf.SHF,
70547056 entsize: std.elf.Xword,
7055 type: std.elf.SHT = .PROGBITS,
7057 /// Must be one of:
7058 /// * `.PROGBITS`
7059 /// * `.NOBITS`
7060 /// * `.X86_64_UNWIND`
7061 type: std.elf.SHT,
70567062}) (Error || error{
70577063 UnsupportedSectionFlags,
70587064 TlsSectionUnavailable,
......@@ -7193,6 +7199,7 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node
71937199 nav.resolved.?.@"threadlocal",
71947200 },
71957201 .entsize = 0,
7202 .type = .PROGBITS,
71967203 })) |shndx| {
71977204 break :section shndx;
71987205 } else |err| switch (err) {
......@@ -7900,27 +7907,32 @@ fn loadObject(
79007907 },
79017908 };
79027909
7903 const placement = sections[input_sym.shndx].placement;
7904
7905 if (placement == .none) continue;
7906
7907 const symbol_oni: MappedFile.Node.Index.Optional, const output_shndx, const symbol_value = switch (placement) {
7910 const symbol_oni: MappedFile.Node.Index.Optional, const output_shndx: Section.Index, const symbol_value: u64 = switch (sections[input_sym.shndx].placement) {
7911 .none => continue,
79087912 .progbits => |isi| .{
79097913 .wrap(isi.node(elf)),
79107914 elf.getNodeShndx(isi.node(elf)),
79117915 input_sym.value,
79127916 },
7913 .nobits => |nobits| .{
7914 .none,
7915 nobits.shndx,
7916 (if (elf.ehdrType() == .REL)
7917 @as(u64, 0)
7918 else if (nobits.shndx.flags(elf).TLS)
7919 elf.tbssBaseOffset()
7920 else
7921 nobits.shndx.vaddr(elf)) + nobits.offset + input_sym.value,
7917 .nobits => |nobits| sym: {
7918 const section_base: u64 = switch (elf.ehdrType()) {
7919 .REL => 0,
7920 .EXEC, .DYN => base: {
7921 if (elf.ni.tls != .none and
7922 nobits.shndx == elf.shndx.tbss)
7923 {
7924 break :base elf.tbssBaseOffset();
7925 }
7926 assert(nobits.shndx == elf.shndx.bss);
7927 break :base nobits.shndx.vaddr(elf);
7928 },
7929 };
7930 break :sym .{
7931 .none,
7932 nobits.shndx,
7933 section_base + nobits.offset + input_sym.value,
7934 };
79227935 },
7923 .none => unreachable,
79247936 };
79257937
79267938 switch (input_sym.info.bind) {
......@@ -9109,15 +9121,18 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
91099121 .EXEC, .DYN => segment_ni,
91109122 };
91119123 assert(opts.addralign.check(opts.size));
9112 const oni: MappedFile.Node.Index.Optional = if (opts.type == .NOBITS) .none else .wrap(elf.addNodeAssumeCapacity(try parent_ni.addFloatingChild(gpa, &elf.mf, .{
9113 .size = opts.node_align.forward(opts.size),
9114 .alignment = opts.addralign.max(opts.node_align),
9115 .resized = opts.size > 0,
9116 .bubbles_moved = opts.flags.ALLOC,
9117 }), switch (opts.manual_size) {
9118 false => .{ .section = shndx },
9119 true => .{ .section_manual_size = shndx },
9120 }));
9124 const oni: MappedFile.Node.Index.Optional = switch (opts.type) {
9125 .NOBITS => .none,
9126 else => .wrap(elf.addNodeAssumeCapacity(
9127 try parent_ni.addFloatingChild(gpa, &elf.mf, .{
9128 .size = opts.node_align.forward(opts.size),
9129 .alignment = opts.addralign.max(opts.node_align),
9130 .resized = opts.size > 0,
9131 .bubbles_moved = opts.flags.ALLOC,
9132 }),
9133 if (opts.manual_size) .{ .section_manual_size = shndx } else .{ .section = shndx },
9134 )),
9135 };
91219136 const addr = if (oni.unwrap()) |ni| elf.computeNodeVAddr(ni) else 0;
91229137 elf.shdrs.appendAssumeCapacity(.{
91239138 .lsi = if (want_symbol) try elf.addLocalSymbol(.{
......@@ -11700,7 +11715,7 @@ fn loadSegmentChildrenMoved(
1170011715 offset: u64,
1170111716 filesz: u64,
1170211717) std.mem.Allocator.Error!void {
11703 if (segment_ni == elf.ni.data and elf.shndx.bss != .UNDEF) {
11718 if (segment_ni == elf.ni.data) {
1170411719 const bss_shndx = elf.shndx.bss;
1170511720 const old_bss_addr = bss_shndx.vaddr(elf);
1170611721 const new_bss_addr = new_vaddr + filesz;