diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 09ea7b6a25e8dcba3cec1d1996266de05863b809..b7045cac54bb00945e2b9a6458d422151aca54ff 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -3546,16 +3546,20 @@ fn objectSectionMapIndex( try coff.symbols.ensureUnusedCapacity(gpa, 1); const parent_ni = parent.node(coff); var prev_oni: MappedFile.Node.Index.Optional = .none; - var next_it = parent_ni.children(&coff.mf); - while (next_it.next()) |next_ni| switch (std.mem.order( - u8, - name_slice, - coff.getNode(next_ni).object_section.name(coff).toSlice(coff), - )) { - .lt => break, - .eq => unreachable, - .gt => prev_oni = .wrap(next_ni), - }; + { + var child_oni = parent_ni.first(&coff.mf); + while (child_oni.unwrap()) |child_ni| : (child_oni = child_ni.next(&coff.mf)) { + switch (std.mem.order( + u8, + name_slice, + coff.getNode(child_ni).object_section.name(coff).toSlice(coff), + )) { + .lt => break, + .eq => unreachable, + .gt => prev_oni = .wrap(child_ni), + } + } + } const ni = try parent_ni.addHeaderChildAfter(&coff.mf, gpa, prev_oni, .{ .alignment = alignment, }); @@ -7025,7 +7029,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { if (coff.isArchive() and coff.members.items.len > 0) { const last_member = coff.members.items[coff.members.items.len - 1]; // See .archive_member branch for reasoning - assert(Node.known.file.reverseChildren(&coff.mf).ni == last_member.content_ni.toOptional()); + assert(Node.known.file.last(&coff.mf).unwrap().? == last_member.content_ni); try coff.flushResized(last_member.content_ni); } }, @@ -7717,30 +7721,31 @@ pub fn printNode( if (mf_node.flags.has_content) " has_content" else "", }); } - var leaf = true; - var child_it = ni.children(&coff.mf); - while (child_it.next()) |child_ni| { - leaf = false; - try coff.printNode(tid, w, child_ni, indent + 1); - } - if (leaf) { - const file_loc = ni.fileLocation(&coff.mf, false); - if (file_loc.size == 0) return; - var address = file_loc.offset; - const line_len = 0x10; - var line_it = std.mem.window( - u8, - coff.mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)], - line_len, - line_len, - ); - while (line_it.next()) |line_bytes| : (address += line_len) { - try w.splatByteAll(' ', indent + 1); - try w.print("{x:0>8} ", .{address}); - for (line_bytes) |byte| try w.print("{x:0>2} ", .{byte}); - try w.splatByteAll(' ', 3 * (line_len - line_bytes.len) + 1); - for (line_bytes) |byte| try w.writeByte(if (std.ascii.isPrint(byte)) byte else '.'); - try w.writeByte('\n'); + if (ni.first(&coff.mf).unwrap()) |first_ni| { + // non-leaf, just print children + var child_ni = first_ni; + while (true) { + try coff.printNode(tid, w, child_ni, indent + 1); + child_ni = child_ni.next(&coff.mf).unwrap() orelse break; } + return; + } + const file_loc = ni.fileLocation(&coff.mf, false); + if (file_loc.size == 0) return; + var address = file_loc.offset; + const line_len = 0x10; + var line_it = std.mem.window( + u8, + coff.mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)], + line_len, + line_len, + ); + while (line_it.next()) |line_bytes| : (address += line_len) { + try w.splatByteAll(' ', indent + 1); + try w.print("{x:0>8} ", .{address}); + for (line_bytes) |byte| try w.print("{x:0>2} ", .{byte}); + try w.splatByteAll(' ', 3 * (line_len - line_bytes.len) + 1); + for (line_bytes) |byte| try w.writeByte(if (std.ascii.isPrint(byte)) byte else '.'); + try w.writeByte('\n'); } } diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index 0acc9a6fe86b17f887eb41a55f35ea199bb1dca7..7f5cbd60fdb44f392a195cf07ad96ff7fcd402f7 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -7902,8 +7902,10 @@ fn flushElfOffset(elf: *Elf, ni: MappedFile.Node.Index) void { } }, } - var child_it = ni.children(&elf.mf); - while (child_it.next()) |child_ni| elf.flushElfOffset(child_ni); + var child_oni = ni.first(&elf.mf); + while (child_oni.unwrap()) |child_ni| : (child_oni = child_ni.next(&elf.mf)) { + elf.flushElfOffset(child_ni); + } }, .section => |shndx| switch (elf.shdrPtr(shndx)) { inline else => |shdr| elf.targetStore(&shdr.offset, @intCast(elf_offset)), @@ -8203,9 +8205,10 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo _, const size = ni.location(&elf.mf).resolve(&elf.mf); switch (elf.getNode(ni)) { .archive => { - var child_it = ni.reverseChildren(&elf.mf); - if (child_it.next()) |last_ni| { - if (child_it.next()) |prev_ni| if (prev_ni.hasNextMoved(&elf.mf)) return; + if (ni.last(&elf.mf).unwrap()) |last_ni| { + if (last_ni.prev(&elf.mf).unwrap()) |prev_ni| { + if (prev_ni.hasNextMoved(&elf.mf)) return; + } const offset, _ = last_ni.location(&elf.mf).resolve(&elf.mf); _ = std.mem.print(&elf.arHdrPtr(last_ni).ar_size, "{d:<10}", .{ size - offset, @@ -8894,13 +8897,15 @@ pub fn printNode( if (mf_node.flags.has_content) " has_content" else "", }); } - var leaf = true; - var child_it = ni.children(&elf.mf); - while (child_it.next()) |child_ni| { - leaf = false; - try elf.printNode(tid, w, child_ni, indent + 1); + if (ni.first(&elf.mf).unwrap()) |first_ni| { + // non-leaf, just print children + var child_ni = first_ni; + while (true) { + try elf.printNode(tid, w, child_ni, indent + 1); + child_ni = child_ni.next(&elf.mf).unwrap() orelse break; + } + return; } - if (!leaf) return; const file_loc = ni.fileLocation(&elf.mf, false); var address = file_loc.offset; if (file_loc.size == 0) { diff --git a/src/link/MappedFile.zig b/src/link/MappedFile.zig index 40af66dbf8c53093c492a79d69064879175cc4ef..a790ecbd3b303fbe97ea860481e41913d2aa3806 100644 --- a/src/link/MappedFile.zig +++ b/src/link/MappedFile.zig @@ -486,24 +486,6 @@ pub const Node = extern struct { return ni.get(mf).prev; } - pub fn ChildIterator(comptime direction: enum { prev, next }) type { - return struct { - mf: *const MappedFile, - ni: Node.Index.Optional, - pub fn next(it: *@This()) ?Node.Index { - const ni = it.ni.unwrap() orelse return null; - it.ni = @field(ni.get(it.mf), @tagName(direction)); - return ni; - } - }; - } - pub fn children(ni: Node.Index, mf: *const MappedFile) ChildIterator(.next) { - return .{ .mf = mf, .ni = ni.get(mf).first }; - } - pub fn reverseChildren(ni: Node.Index, mf: *const MappedFile) ChildIterator(.prev) { - return .{ .mf = mf, .ni = ni.get(mf).last }; - } - pub fn childrenMoved(ni: Node.Index, gpa: Allocator, mf: *MappedFile) Allocator.Error!void { var child_oni = ni.get(mf).last; while (child_oni.unwrap()) |child_ni| {