| ... | @@ -684,16 +684,18 @@ const Section = struct { | ... | @@ -684,16 +684,18 @@ const Section = struct { |
| 684 | } | 684 | } |
| 685 | } else { | 685 | } else { |
| 686 | // For sections without nodes (NOBITS), propagate alignment to the parent. | 686 | // For sections without nodes (NOBITS), propagate alignment to the parent. |
| 687 | assert(switch (elf.shdrPtr(shndx)) { | 687 | switch (elf.shdrPtr(shndx)) { |
| 688 | inline else => |shdr| elf.targetLoad(&shdr.type) == .NOBITS, | 688 | inline else => |shdr| assert(elf.targetLoad(&shdr.type) == .NOBITS), |
| 689 | }); | 689 | } |
| 690 | | 690 | |
| 691 | if (elf.ehdrType() == .REL) return; | 691 | if (elf.ehdrType() == .REL) return; |
| 692 | | 692 | |
| 693 | const segment_ni = if (shndx.flags(elf).TLS) | 693 | const segment_ni: MappedFile.Node.Index = seg: { |
| 694 | elf.ni.tls.unwrap().? | 694 | if (shndx == elf.shndx.bss) break :seg elf.ni.data; |
| 695 | else | 695 | if (shndx == elf.shndx.tbss) break :seg elf.ni.tls.unwrap().?; |
| 696 | elf.ni.data; | 696 | // NOBITS sections other than `.bss` and `.tbss` are only emitted in `ET_REL`s. |
| | 697 | unreachable; |
| | 698 | }; |
| 697 | | 699 | |
| 698 | try elf.ensureSegmentAligned(elf.getNode(segment_ni).segment, min_align); | 700 | try elf.ensureSegmentAligned(elf.getNode(segment_ni).segment, min_align); |
| 699 | } | 701 | } |
| ... | @@ -7052,7 +7054,11 @@ fn mapInputSection(elf: *Elf, opts: struct { | ... | @@ -7052,7 +7054,11 @@ fn mapInputSection(elf: *Elf, opts: struct { |
| 7052 | name: []const u8, | 7054 | name: []const u8, |
| 7053 | flags: std.elf.SHF, | 7055 | flags: std.elf.SHF, |
| 7054 | entsize: std.elf.Xword, | 7056 | 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, |
| 7056 | }) (Error || error{ | 7062 | }) (Error || error{ |
| 7057 | UnsupportedSectionFlags, | 7063 | UnsupportedSectionFlags, |
| 7058 | TlsSectionUnavailable, | 7064 | TlsSectionUnavailable, |
| ... | @@ -7193,6 +7199,7 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node | ... | @@ -7193,6 +7199,7 @@ fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node |
| 7193 | nav.resolved.?.@"threadlocal", | 7199 | nav.resolved.?.@"threadlocal", |
| 7194 | }, | 7200 | }, |
| 7195 | .entsize = 0, | 7201 | .entsize = 0, |
| | 7202 | .type = .PROGBITS, |
| 7196 | })) |shndx| { | 7203 | })) |shndx| { |
| 7197 | break :section shndx; | 7204 | break :section shndx; |
| 7198 | } else |err| switch (err) { | 7205 | } else |err| switch (err) { |
| ... | @@ -7900,27 +7907,32 @@ fn loadObject( | ... | @@ -7900,27 +7907,32 @@ fn loadObject( |
| 7900 | }, | 7907 | }, |
| 7901 | }; | 7908 | }; |
| 7902 | | 7909 | |
| 7903 | const placement = sections[input_sym.shndx].placement; | 7910 | const symbol_oni: MappedFile.Node.Index.Optional, const output_shndx: Section.Index, const symbol_value: u64 = switch (sections[input_sym.shndx].placement) { |
| 7904 | | 7911 | .none => continue, |
| 7905 | if (placement == .none) continue; | | |
| 7906 | | | |
| 7907 | const symbol_oni: MappedFile.Node.Index.Optional, const output_shndx, const symbol_value = switch (placement) { | | |
| 7908 | .progbits => |isi| .{ | 7912 | .progbits => |isi| .{ |
| 7909 | .wrap(isi.node(elf)), | 7913 | .wrap(isi.node(elf)), |
| 7910 | elf.getNodeShndx(isi.node(elf)), | 7914 | elf.getNodeShndx(isi.node(elf)), |
| 7911 | input_sym.value, | 7915 | input_sym.value, |
| 7912 | }, | 7916 | }, |
| 7913 | .nobits => |nobits| .{ | 7917 | .nobits => |nobits| sym: { |
| 7914 | .none, | 7918 | const section_base: u64 = switch (elf.ehdrType()) { |
| 7915 | nobits.shndx, | 7919 | .REL => 0, |
| 7916 | (if (elf.ehdrType() == .REL) | 7920 | .EXEC, .DYN => base: { |
| 7917 | @as(u64, 0) | 7921 | if (elf.ni.tls != .none and |
| 7918 | else if (nobits.shndx.flags(elf).TLS) | 7922 | nobits.shndx == elf.shndx.tbss) |
| 7919 | elf.tbssBaseOffset() | 7923 | { |
| 7920 | else | 7924 | break :base elf.tbssBaseOffset(); |
| 7921 | nobits.shndx.vaddr(elf)) + nobits.offset + input_sym.value, | 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 | }; |
| 7922 | }, | 7935 | }, |
| 7923 | .none => unreachable, | | |
| 7924 | }; | 7936 | }; |
| 7925 | | 7937 | |
| 7926 | switch (input_sym.info.bind) { | 7938 | switch (input_sym.info.bind) { |
| ... | @@ -9109,15 +9121,18 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { | ... | @@ -9109,15 +9121,18 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 9109 | .EXEC, .DYN => segment_ni, | 9121 | .EXEC, .DYN => segment_ni, |
| 9110 | }; | 9122 | }; |
| 9111 | assert(opts.addralign.check(opts.size)); | 9123 | 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, .{ | 9124 | const oni: MappedFile.Node.Index.Optional = switch (opts.type) { |
| 9113 | .size = opts.node_align.forward(opts.size), | 9125 | .NOBITS => .none, |
| 9114 | .alignment = opts.addralign.max(opts.node_align), | 9126 | else => .wrap(elf.addNodeAssumeCapacity( |
| 9115 | .resized = opts.size > 0, | 9127 | try parent_ni.addFloatingChild(gpa, &elf.mf, .{ |
| 9116 | .bubbles_moved = opts.flags.ALLOC, | 9128 | .size = opts.node_align.forward(opts.size), |
| 9117 | }), switch (opts.manual_size) { | 9129 | .alignment = opts.addralign.max(opts.node_align), |
| 9118 | false => .{ .section = shndx }, | 9130 | .resized = opts.size > 0, |
| 9119 | true => .{ .section_manual_size = shndx }, | 9131 | .bubbles_moved = opts.flags.ALLOC, |
| 9120 | })); | 9132 | }), |
| | 9133 | if (opts.manual_size) .{ .section_manual_size = shndx } else .{ .section = shndx }, |
| | 9134 | )), |
| | 9135 | }; |
| 9121 | const addr = if (oni.unwrap()) |ni| elf.computeNodeVAddr(ni) else 0; | 9136 | const addr = if (oni.unwrap()) |ni| elf.computeNodeVAddr(ni) else 0; |
| 9122 | elf.shdrs.appendAssumeCapacity(.{ | 9137 | elf.shdrs.appendAssumeCapacity(.{ |
| 9123 | .lsi = if (want_symbol) try elf.addLocalSymbol(.{ | 9138 | .lsi = if (want_symbol) try elf.addLocalSymbol(.{ |
| ... | @@ -11700,7 +11715,7 @@ fn loadSegmentChildrenMoved( | ... | @@ -11700,7 +11715,7 @@ fn loadSegmentChildrenMoved( |
| 11700 | offset: u64, | 11715 | offset: u64, |
| 11701 | filesz: u64, | 11716 | filesz: u64, |
| 11702 | ) std.mem.Allocator.Error!void { | 11717 | ) std.mem.Allocator.Error!void { |
| 11703 | if (segment_ni == elf.ni.data and elf.shndx.bss != .UNDEF) { | 11718 | if (segment_ni == elf.ni.data) { |
| 11704 | const bss_shndx = elf.shndx.bss; | 11719 | const bss_shndx = elf.shndx.bss; |
| 11705 | const old_bss_addr = bss_shndx.vaddr(elf); | 11720 | const old_bss_addr = bss_shndx.vaddr(elf); |
| 11706 | const new_bss_addr = new_vaddr + filesz; | 11721 | const new_bss_addr = new_vaddr + filesz; |