| author | |
| committer | |
| log | 7ece5e656da5cdd991f9fd1cb289f71c586a9210 |
| tree | 1b45d684c0f3548f263cb020c7ce1594aceb3070 |
| parent | 96c9ff1c93532e7c2764449e0cd6f39d4dce2285 |
| signature |
There are now functions for `first`, `last`, `prev`, and `next`, so
there is no need for a separate abstraction wrapping a simple linked
list iteration.3 files changed, 56 insertions(+), 64 deletions(-)
src/link/Coff.zig+40-35| ... | @@ -3546,16 +3546,20 @@ fn objectSectionMapIndex( | ... | @@ -3546,16 +3546,20 @@ fn objectSectionMapIndex( |
| 3546 | try coff.symbols.ensureUnusedCapacity(gpa, 1); | 3546 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 3547 | const parent_ni = parent.node(coff); | 3547 | const parent_ni = parent.node(coff); |
| 3548 | var prev_oni: MappedFile.Node.Index.Optional = .none; | 3548 | var prev_oni: MappedFile.Node.Index.Optional = .none; |
| 3549 | var next_it = parent_ni.children(&coff.mf); | 3549 | { |
| 3550 | while (next_it.next()) |next_ni| switch (std.mem.order( | 3550 | var child_oni = parent_ni.first(&coff.mf); |
| 3551 | u8, | 3551 | while (child_oni.unwrap()) |child_ni| : (child_oni = child_ni.next(&coff.mf)) { |
| 3552 | name_slice, | 3552 | switch (std.mem.order( |
| 3553 | coff.getNode(next_ni).object_section.name(coff).toSlice(coff), | 3553 | u8, |
| 3554 | )) { | 3554 | name_slice, |
| 3555 | .lt => break, | 3555 | coff.getNode(child_ni).object_section.name(coff).toSlice(coff), |
| 3556 | .eq => unreachable, | 3556 | )) { |
| 3557 | .gt => prev_oni = .wrap(next_ni), | 3557 | .lt => break, |
| 3558 | }; | 3558 | .eq => unreachable, |
| 3559 | .gt => prev_oni = .wrap(child_ni), | ||
| 3560 | } | ||
| 3561 | } | ||
| 3562 | } | ||
| 3559 | const ni = try parent_ni.addHeaderChildAfter(&coff.mf, gpa, prev_oni, .{ | 3563 | const ni = try parent_ni.addHeaderChildAfter(&coff.mf, gpa, prev_oni, .{ |
| 3560 | .alignment = alignment, | 3564 | .alignment = alignment, |
| 3561 | }); | 3565 | }); |
| ... | @@ -7025,7 +7029,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { | ... | @@ -7025,7 +7029,7 @@ fn flushResized(coff: *Coff, ni: MappedFile.Node.Index) !void { |
| 7025 | if (coff.isArchive() and coff.members.items.len > 0) { | 7029 | if (coff.isArchive() and coff.members.items.len > 0) { |
| 7026 | const last_member = coff.members.items[coff.members.items.len - 1]; | 7030 | const last_member = coff.members.items[coff.members.items.len - 1]; |
| 7027 | // See .archive_member branch for reasoning | 7031 | // See .archive_member branch for reasoning |
| 7028 | assert(Node.known.file.reverseChildren(&coff.mf).ni == last_member.content_ni.toOptional()); | 7032 | assert(Node.known.file.last(&coff.mf).unwrap().? == last_member.content_ni); |
| 7029 | try coff.flushResized(last_member.content_ni); | 7033 | try coff.flushResized(last_member.content_ni); |
| 7030 | } | 7034 | } |
| 7031 | }, | 7035 | }, |
| ... | @@ -7717,30 +7721,31 @@ pub fn printNode( | ... | @@ -7717,30 +7721,31 @@ pub fn printNode( |
| 7717 | if (mf_node.flags.has_content) " has_content" else "", | 7721 | if (mf_node.flags.has_content) " has_content" else "", |
| 7718 | }); | 7722 | }); |
| 7719 | } | 7723 | } |
| 7720 | var leaf = true; | 7724 | if (ni.first(&coff.mf).unwrap()) |first_ni| { |
| 7721 | var child_it = ni.children(&coff.mf); | 7725 | // non-leaf, just print children |
| 7722 | while (child_it.next()) |child_ni| { | 7726 | var child_ni = first_ni; |
| 7723 | leaf = false; | 7727 | while (true) { |
| 7724 | try coff.printNode(tid, w, child_ni, indent + 1); | 7728 | try coff.printNode(tid, w, child_ni, indent + 1); |
| 7725 | } | 7729 | child_ni = child_ni.next(&coff.mf).unwrap() orelse break; |
| 7726 | if (leaf) { | ||
| 7727 | const file_loc = ni.fileLocation(&coff.mf, false); | ||
| 7728 | if (file_loc.size == 0) return; | ||
| 7729 | var address = file_loc.offset; | ||
| 7730 | const line_len = 0x10; | ||
| 7731 | var line_it = std.mem.window( | ||
| 7732 | u8, | ||
| 7733 | coff.mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)], | ||
| 7734 | line_len, | ||
| 7735 | line_len, | ||
| 7736 | ); | ||
| 7737 | while (line_it.next()) |line_bytes| : (address += line_len) { | ||
| 7738 | try w.splatByteAll(' ', indent + 1); | ||
| 7739 | try w.print("{x:0>8} ", .{address}); | ||
| 7740 | for (line_bytes) |byte| try w.print("{x:0>2} ", .{byte}); | ||
| 7741 | try w.splatByteAll(' ', 3 * (line_len - line_bytes.len) + 1); | ||
| 7742 | for (line_bytes) |byte| try w.writeByte(if (std.ascii.isPrint(byte)) byte else '.'); | ||
| 7743 | try w.writeByte('\n'); | ||
| 7744 | } | 7730 | } |
| 7731 | return; | ||
| 7732 | } | ||
| 7733 | const file_loc = ni.fileLocation(&coff.mf, false); | ||
| 7734 | if (file_loc.size == 0) return; | ||
| 7735 | var address = file_loc.offset; | ||
| 7736 | const line_len = 0x10; | ||
| 7737 | var line_it = std.mem.window( | ||
| 7738 | u8, | ||
| 7739 | coff.mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)], | ||
| 7740 | line_len, | ||
| 7741 | line_len, | ||
| 7742 | ); | ||
| 7743 | while (line_it.next()) |line_bytes| : (address += line_len) { | ||
| 7744 | try w.splatByteAll(' ', indent + 1); | ||
| 7745 | try w.print("{x:0>8} ", .{address}); | ||
| 7746 | for (line_bytes) |byte| try w.print("{x:0>2} ", .{byte}); | ||
| 7747 | try w.splatByteAll(' ', 3 * (line_len - line_bytes.len) + 1); | ||
| 7748 | for (line_bytes) |byte| try w.writeByte(if (std.ascii.isPrint(byte)) byte else '.'); | ||
| 7749 | try w.writeByte('\n'); | ||
| 7745 | } | 7750 | } |
| 7746 | } | 7751 | } |
src/link/Elf2.zig+16-11| ... | @@ -7902,8 +7902,10 @@ fn flushElfOffset(elf: *Elf, ni: MappedFile.Node.Index) void { | ... | @@ -7902,8 +7902,10 @@ fn flushElfOffset(elf: *Elf, ni: MappedFile.Node.Index) void { |
| 7902 | } | 7902 | } |
| 7903 | }, | 7903 | }, |
| 7904 | } | 7904 | } |
| 7905 | var child_it = ni.children(&elf.mf); | 7905 | var child_oni = ni.first(&elf.mf); |
| 7906 | while (child_it.next()) |child_ni| elf.flushElfOffset(child_ni); | 7906 | while (child_oni.unwrap()) |child_ni| : (child_oni = child_ni.next(&elf.mf)) { |
| 7907 | elf.flushElfOffset(child_ni); | ||
| 7908 | } | ||
| 7907 | }, | 7909 | }, |
| 7908 | .section => |shndx| switch (elf.shdrPtr(shndx)) { | 7910 | .section => |shndx| switch (elf.shdrPtr(shndx)) { |
| 7909 | inline else => |shdr| elf.targetStore(&shdr.offset, @intCast(elf_offset)), | 7911 | 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 | ... | @@ -8203,9 +8205,10 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo |
| 8203 | _, const size = ni.location(&elf.mf).resolve(&elf.mf); | 8205 | _, const size = ni.location(&elf.mf).resolve(&elf.mf); |
| 8204 | switch (elf.getNode(ni)) { | 8206 | switch (elf.getNode(ni)) { |
| 8205 | .archive => { | 8207 | .archive => { |
| 8206 | var child_it = ni.reverseChildren(&elf.mf); | 8208 | if (ni.last(&elf.mf).unwrap()) |last_ni| { |
| 8207 | if (child_it.next()) |last_ni| { | 8209 | if (last_ni.prev(&elf.mf).unwrap()) |prev_ni| { |
| 8208 | if (child_it.next()) |prev_ni| if (prev_ni.hasNextMoved(&elf.mf)) return; | 8210 | if (prev_ni.hasNextMoved(&elf.mf)) return; |
| 8211 | } | ||
| 8209 | const offset, _ = last_ni.location(&elf.mf).resolve(&elf.mf); | 8212 | const offset, _ = last_ni.location(&elf.mf).resolve(&elf.mf); |
| 8210 | _ = std.mem.print(&elf.arHdrPtr(last_ni).ar_size, "{d:<10}", .{ | 8213 | _ = std.mem.print(&elf.arHdrPtr(last_ni).ar_size, "{d:<10}", .{ |
| 8211 | size - offset, | 8214 | size - offset, |
| ... | @@ -8894,13 +8897,15 @@ pub fn printNode( | ... | @@ -8894,13 +8897,15 @@ pub fn printNode( |
| 8894 | if (mf_node.flags.has_content) " has_content" else "", | 8897 | if (mf_node.flags.has_content) " has_content" else "", |
| 8895 | }); | 8898 | }); |
| 8896 | } | 8899 | } |
| 8897 | var leaf = true; | 8900 | if (ni.first(&elf.mf).unwrap()) |first_ni| { |
| 8898 | var child_it = ni.children(&elf.mf); | 8901 | // non-leaf, just print children |
| 8899 | while (child_it.next()) |child_ni| { | 8902 | var child_ni = first_ni; |
| 8900 | leaf = false; | 8903 | while (true) { |
| 8901 | try elf.printNode(tid, w, child_ni, indent + 1); | 8904 | try elf.printNode(tid, w, child_ni, indent + 1); |
| 8905 | child_ni = child_ni.next(&elf.mf).unwrap() orelse break; | ||
| 8906 | } | ||
| 8907 | return; | ||
| 8902 | } | 8908 | } |
| 8903 | if (!leaf) return; | ||
| 8904 | const file_loc = ni.fileLocation(&elf.mf, false); | 8909 | const file_loc = ni.fileLocation(&elf.mf, false); |
| 8905 | var address = file_loc.offset; | 8910 | var address = file_loc.offset; |
| 8906 | if (file_loc.size == 0) { | 8911 | if (file_loc.size == 0) { |
src/link/MappedFile.zig-18| ... | @@ -486,24 +486,6 @@ pub const Node = extern struct { | ... | @@ -486,24 +486,6 @@ pub const Node = extern struct { |
| 486 | return ni.get(mf).prev; | 486 | return ni.get(mf).prev; |
| 487 | } | 487 | } |
| 488 | 488 | ||
| 489 | pub fn ChildIterator(comptime direction: enum { prev, next }) type { | ||
| 490 | return struct { | ||
| 491 | mf: *const MappedFile, | ||
| 492 | ni: Node.Index.Optional, | ||
| 493 | pub fn next(it: *@This()) ?Node.Index { | ||
| 494 | const ni = it.ni.unwrap() orelse return null; | ||
| 495 | it.ni = @field(ni.get(it.mf), @tagName(direction)); | ||
| 496 | return ni; | ||
| 497 | } | ||
| 498 | }; | ||
| 499 | } | ||
| 500 | pub fn children(ni: Node.Index, mf: *const MappedFile) ChildIterator(.next) { | ||
| 501 | return .{ .mf = mf, .ni = ni.get(mf).first }; | ||
| 502 | } | ||
| 503 | pub fn reverseChildren(ni: Node.Index, mf: *const MappedFile) ChildIterator(.prev) { | ||
| 504 | return .{ .mf = mf, .ni = ni.get(mf).last }; | ||
| 505 | } | ||
| 506 | |||
| 507 | pub fn childrenMoved(ni: Node.Index, gpa: Allocator, mf: *MappedFile) Allocator.Error!void { | 489 | pub fn childrenMoved(ni: Node.Index, gpa: Allocator, mf: *MappedFile) Allocator.Error!void { |
| 508 | var child_oni = ni.get(mf).last; | 490 | var child_oni = ni.get(mf).last; |
| 509 | while (child_oni.unwrap()) |child_ni| { | 491 | while (child_oni.unwrap()) |child_ni| { |