mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
std.Io: delete CountingReader
This commit is contained in:
parent
4b948e8556
commit
558bea2a76
7 changed files with 77 additions and 174 deletions
|
|
@ -1224,14 +1224,12 @@ const MachODumper = struct {
|
|||
}
|
||||
|
||||
fn parseRebaseInfo(ctx: ObjectContext, data: []const u8, rebases: *std.array_list.Managed(u64)) !void {
|
||||
var stream = std.io.fixedBufferStream(data);
|
||||
var creader = std.io.countingReader(stream.reader());
|
||||
const reader = creader.reader();
|
||||
var reader: std.Io.Reader = .fixed(data);
|
||||
|
||||
var seg_id: ?u8 = null;
|
||||
var offset: u64 = 0;
|
||||
while (true) {
|
||||
const byte = reader.readByte() catch break;
|
||||
const byte = reader.takeByte() catch break;
|
||||
const opc = byte & macho.REBASE_OPCODE_MASK;
|
||||
const imm = byte & macho.REBASE_IMMEDIATE_MASK;
|
||||
switch (opc) {
|
||||
|
|
@ -1239,17 +1237,17 @@ const MachODumper = struct {
|
|||
macho.REBASE_OPCODE_SET_TYPE_IMM => {},
|
||||
macho.REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB => {
|
||||
seg_id = imm;
|
||||
offset = try std.leb.readUleb128(u64, reader);
|
||||
offset = try reader.takeLeb128(u64);
|
||||
},
|
||||
macho.REBASE_OPCODE_ADD_ADDR_IMM_SCALED => {
|
||||
offset += imm * @sizeOf(u64);
|
||||
},
|
||||
macho.REBASE_OPCODE_ADD_ADDR_ULEB => {
|
||||
const addend = try std.leb.readUleb128(u64, reader);
|
||||
const addend = try reader.takeLeb128(u64);
|
||||
offset += addend;
|
||||
},
|
||||
macho.REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB => {
|
||||
const addend = try std.leb.readUleb128(u64, reader);
|
||||
const addend = try reader.takeLeb128(u64);
|
||||
const seg = ctx.segments.items[seg_id.?];
|
||||
const addr = seg.vmaddr + offset;
|
||||
try rebases.append(addr);
|
||||
|
|
@ -1266,11 +1264,11 @@ const MachODumper = struct {
|
|||
ntimes = imm;
|
||||
},
|
||||
macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES => {
|
||||
ntimes = try std.leb.readUleb128(u64, reader);
|
||||
ntimes = try reader.takeLeb128(u64);
|
||||
},
|
||||
macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB => {
|
||||
ntimes = try std.leb.readUleb128(u64, reader);
|
||||
skip = try std.leb.readUleb128(u64, reader);
|
||||
ntimes = try reader.takeLeb128(u64);
|
||||
skip = try reader.takeLeb128(u64);
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
|
|
@ -1431,7 +1429,7 @@ const MachODumper = struct {
|
|||
defer arena.deinit();
|
||||
|
||||
var exports = std.array_list.Managed(Export).init(arena.allocator());
|
||||
var it = TrieIterator{ .data = data };
|
||||
var it: TrieIterator = .{ .stream = .fixed(data) };
|
||||
try parseTrieNode(arena.allocator(), &it, "", &exports);
|
||||
|
||||
mem.sort(Export, exports.items, {}, Export.lessThan);
|
||||
|
|
@ -1462,42 +1460,18 @@ const MachODumper = struct {
|
|||
}
|
||||
|
||||
const TrieIterator = struct {
|
||||
data: []const u8,
|
||||
pos: usize = 0,
|
||||
|
||||
fn getStream(it: *TrieIterator) std.io.FixedBufferStream([]const u8) {
|
||||
return std.io.fixedBufferStream(it.data[it.pos..]);
|
||||
}
|
||||
stream: std.Io.Reader,
|
||||
|
||||
fn readUleb128(it: *TrieIterator) !u64 {
|
||||
var stream = it.getStream();
|
||||
var creader = std.io.countingReader(stream.reader());
|
||||
const reader = creader.reader();
|
||||
const value = try std.leb.readUleb128(u64, reader);
|
||||
it.pos += creader.bytes_read;
|
||||
return value;
|
||||
return it.stream.takeLeb128(u64);
|
||||
}
|
||||
|
||||
fn readString(it: *TrieIterator) ![:0]const u8 {
|
||||
var stream = it.getStream();
|
||||
const reader = stream.reader();
|
||||
|
||||
var count: usize = 0;
|
||||
while (true) : (count += 1) {
|
||||
const byte = try reader.readByte();
|
||||
if (byte == 0) break;
|
||||
}
|
||||
|
||||
const str = @as([*:0]const u8, @ptrCast(it.data.ptr + it.pos))[0..count :0];
|
||||
it.pos += count + 1;
|
||||
return str;
|
||||
return it.stream.takeSentinel(0);
|
||||
}
|
||||
|
||||
fn readByte(it: *TrieIterator) !u8 {
|
||||
var stream = it.getStream();
|
||||
const value = try stream.reader().readByte();
|
||||
it.pos += 1;
|
||||
return value;
|
||||
return it.stream.takeByte();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1594,10 +1568,10 @@ const MachODumper = struct {
|
|||
const label = try it.readString();
|
||||
const off = try it.readUleb128();
|
||||
const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label });
|
||||
const curr = it.pos;
|
||||
it.pos = off;
|
||||
const curr = it.stream.seek;
|
||||
it.stream.seek = off;
|
||||
try parseTrieNode(arena, it, prefix_label, exports);
|
||||
it.pos = curr;
|
||||
it.stream.seek = curr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -277,10 +277,6 @@ pub const AnyReader = @import("Io/DeprecatedReader.zig");
|
|||
pub const FixedBufferStream = @import("Io/fixed_buffer_stream.zig").FixedBufferStream;
|
||||
/// Deprecated in favor of `Reader`.
|
||||
pub const fixedBufferStream = @import("Io/fixed_buffer_stream.zig").fixedBufferStream;
|
||||
/// Deprecated with no replacement; inefficient pattern
|
||||
pub const CountingReader = @import("Io/counting_reader.zig").CountingReader;
|
||||
/// Deprecated with no replacement; inefficient pattern
|
||||
pub const countingReader = @import("Io/counting_reader.zig").countingReader;
|
||||
|
||||
pub const tty = @import("Io/tty.zig");
|
||||
|
||||
|
|
@ -750,7 +746,6 @@ pub fn PollFiles(comptime StreamEnum: type) type {
|
|||
test {
|
||||
_ = Reader;
|
||||
_ = Writer;
|
||||
_ = CountingReader;
|
||||
_ = FixedBufferStream;
|
||||
_ = tty;
|
||||
_ = @import("Io/test.zig");
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
const std = @import("../std.zig");
|
||||
const io = std.io;
|
||||
const testing = std.testing;
|
||||
|
||||
/// A Reader that counts how many bytes has been read from it.
|
||||
pub fn CountingReader(comptime ReaderType: anytype) type {
|
||||
return struct {
|
||||
child_reader: ReaderType,
|
||||
bytes_read: u64 = 0,
|
||||
|
||||
pub const Error = ReaderType.Error;
|
||||
pub const Reader = io.GenericReader(*@This(), Error, read);
|
||||
|
||||
pub fn read(self: *@This(), buf: []u8) Error!usize {
|
||||
const amt = try self.child_reader.read(buf);
|
||||
self.bytes_read += amt;
|
||||
return amt;
|
||||
}
|
||||
|
||||
pub fn reader(self: *@This()) Reader {
|
||||
return .{ .context = self };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn countingReader(reader: anytype) CountingReader(@TypeOf(reader)) {
|
||||
return .{ .child_reader = reader };
|
||||
}
|
||||
|
||||
test CountingReader {
|
||||
const bytes = "yay" ** 100;
|
||||
var fbs = io.fixedBufferStream(bytes);
|
||||
|
||||
var counting_stream = countingReader(fbs.reader());
|
||||
const stream = counting_stream.reader();
|
||||
|
||||
//read and discard all bytes
|
||||
while (stream.readByte()) |_| {} else |err| {
|
||||
try testing.expect(err == error.EndOfStream);
|
||||
}
|
||||
|
||||
try testing.expect(counting_stream.bytes_read == bytes.len);
|
||||
}
|
||||
|
|
@ -17,12 +17,16 @@ const Rex = encoder.Rex;
|
|||
|
||||
pub const Error = error{
|
||||
EndOfStream,
|
||||
/// After the TODO below is solved this will make sense.
|
||||
ReadFailed,
|
||||
LegacyPrefixAfterRex,
|
||||
UnknownOpcode,
|
||||
Overflow,
|
||||
Todo,
|
||||
};
|
||||
|
||||
// TODO these fields should be replaced by std.Io.Reader
|
||||
|
||||
code: []const u8,
|
||||
pos: usize = 0,
|
||||
|
||||
|
|
@ -388,20 +392,20 @@ fn parseGpRegister(low_enc: u3, is_extended: bool, rex: Rex, bit_size: u64) Regi
|
|||
}
|
||||
|
||||
fn parseImm(dis: *Disassembler, kind: Encoding.Op) !Immediate {
|
||||
var stream = std.io.fixedBufferStream(dis.code[dis.pos..]);
|
||||
var creader = std.io.countingReader(stream.reader());
|
||||
const reader = creader.reader();
|
||||
var reader: std.Io.Reader = .fixed(dis.code);
|
||||
reader.seek = dis.pos;
|
||||
defer dis.pos = reader.seek;
|
||||
|
||||
const imm = switch (kind) {
|
||||
.imm8s, .rel8 => Immediate.s(try reader.readInt(i8, .little)),
|
||||
.imm16s, .rel16 => Immediate.s(try reader.readInt(i16, .little)),
|
||||
.imm32s, .rel32 => Immediate.s(try reader.readInt(i32, .little)),
|
||||
.imm8 => Immediate.u(try reader.readInt(u8, .little)),
|
||||
.imm16 => Immediate.u(try reader.readInt(u16, .little)),
|
||||
.imm32 => Immediate.u(try reader.readInt(u32, .little)),
|
||||
.imm64 => Immediate.u(try reader.readInt(u64, .little)),
|
||||
.imm8s, .rel8 => Immediate.s(try reader.takeInt(i8, .little)),
|
||||
.imm16s, .rel16 => Immediate.s(try reader.takeInt(i16, .little)),
|
||||
.imm32s, .rel32 => Immediate.s(try reader.takeInt(i32, .little)),
|
||||
.imm8 => Immediate.u(try reader.takeInt(u8, .little)),
|
||||
.imm16 => Immediate.u(try reader.takeInt(u16, .little)),
|
||||
.imm32 => Immediate.u(try reader.takeInt(u32, .little)),
|
||||
.imm64 => Immediate.u(try reader.takeInt(u64, .little)),
|
||||
else => unreachable,
|
||||
};
|
||||
dis.pos += std.math.cast(usize, creader.bytes_read) orelse return error.Overflow;
|
||||
return imm;
|
||||
}
|
||||
|
||||
|
|
@ -483,25 +487,25 @@ fn parseSibByte(dis: *Disassembler) !Sib {
|
|||
}
|
||||
|
||||
fn parseDisplacement(dis: *Disassembler, modrm: ModRm, sib: ?Sib) !i32 {
|
||||
var stream = std.io.fixedBufferStream(dis.code[dis.pos..]);
|
||||
var creader = std.io.countingReader(stream.reader());
|
||||
const reader = creader.reader();
|
||||
var reader: std.Io.Reader = .fixed(dis.code);
|
||||
reader.seek = dis.pos;
|
||||
defer dis.pos = reader.seek;
|
||||
|
||||
const disp = disp: {
|
||||
if (sib) |info| {
|
||||
if (info.base == 0b101 and modrm.mod == 0) {
|
||||
break :disp try reader.readInt(i32, .little);
|
||||
break :disp try reader.takeInt(i32, .little);
|
||||
}
|
||||
}
|
||||
if (modrm.rip()) {
|
||||
break :disp try reader.readInt(i32, .little);
|
||||
break :disp try reader.takeInt(i32, .little);
|
||||
}
|
||||
break :disp switch (modrm.mod) {
|
||||
0b00 => 0,
|
||||
0b01 => try reader.readInt(i8, .little),
|
||||
0b10 => try reader.readInt(i32, .little),
|
||||
0b01 => try reader.takeInt(i8, .little),
|
||||
0b10 => try reader.takeInt(i32, .little),
|
||||
0b11 => unreachable,
|
||||
};
|
||||
};
|
||||
dis.pos += std.math.cast(usize, creader.bytes_read) orelse return error.Overflow;
|
||||
return disp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,19 +273,19 @@ pub const InfoReader = struct {
|
|||
}
|
||||
|
||||
pub fn readUleb128(p: *InfoReader, comptime Type: type) !Type {
|
||||
var stream = std.io.fixedBufferStream(p.bytes()[p.pos..]);
|
||||
var creader = std.io.countingReader(stream.reader());
|
||||
const value: Type = try leb.readUleb128(Type, creader.reader());
|
||||
p.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow;
|
||||
return value;
|
||||
var reader: std.Io.Reader = .fixed(p.bytes());
|
||||
reader.seek = p.pos;
|
||||
defer p.pos = reader.seek;
|
||||
|
||||
return reader.takeLeb128(Type);
|
||||
}
|
||||
|
||||
pub fn readIleb128(p: *InfoReader, comptime Type: type) !Type {
|
||||
var stream = std.io.fixedBufferStream(p.bytes()[p.pos..]);
|
||||
var creader = std.io.countingReader(stream.reader());
|
||||
const value: Type = try leb.readIleb128(Type, creader.reader());
|
||||
p.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow;
|
||||
return value;
|
||||
var reader: std.Io.Reader = .fixed(p.bytes());
|
||||
reader.seek = p.pos;
|
||||
defer p.pos = reader.seek;
|
||||
|
||||
return reader.takeLeb128(Type);
|
||||
}
|
||||
|
||||
pub fn seekTo(p: *InfoReader, off: u64) !void {
|
||||
|
|
@ -340,11 +340,11 @@ pub const AbbrevReader = struct {
|
|||
}
|
||||
|
||||
pub fn readUleb128(p: *AbbrevReader, comptime Type: type) !Type {
|
||||
var stream = std.io.fixedBufferStream(p.bytes()[p.pos..]);
|
||||
var creader = std.io.countingReader(stream.reader());
|
||||
const value: Type = try leb.readUleb128(Type, creader.reader());
|
||||
p.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow;
|
||||
return value;
|
||||
var reader: std.Io.Reader = .fixed(p.bytes());
|
||||
reader.seek = p.pos;
|
||||
defer p.pos = reader.seek;
|
||||
|
||||
return reader.takeLeb128(Type);
|
||||
}
|
||||
|
||||
pub fn seekTo(p: *AbbrevReader, off: u64) !void {
|
||||
|
|
|
|||
|
|
@ -159,42 +159,18 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void {
|
|||
}
|
||||
|
||||
const TrieIterator = struct {
|
||||
data: []const u8,
|
||||
pos: usize = 0,
|
||||
|
||||
fn getStream(it: *TrieIterator) std.io.FixedBufferStream([]const u8) {
|
||||
return std.io.fixedBufferStream(it.data[it.pos..]);
|
||||
}
|
||||
stream: std.Io.Reader,
|
||||
|
||||
fn readUleb128(it: *TrieIterator) !u64 {
|
||||
var stream = it.getStream();
|
||||
var creader = std.io.countingReader(stream.reader());
|
||||
const reader = creader.reader();
|
||||
const value = try std.leb.readUleb128(u64, reader);
|
||||
it.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow;
|
||||
return value;
|
||||
return it.stream.takeLeb128(u64);
|
||||
}
|
||||
|
||||
fn readString(it: *TrieIterator) ![:0]const u8 {
|
||||
var stream = it.getStream();
|
||||
const reader = stream.reader();
|
||||
|
||||
var count: usize = 0;
|
||||
while (true) : (count += 1) {
|
||||
const byte = try reader.readByte();
|
||||
if (byte == 0) break;
|
||||
}
|
||||
|
||||
const str = @as([*:0]const u8, @ptrCast(it.data.ptr + it.pos))[0..count :0];
|
||||
it.pos += count + 1;
|
||||
return str;
|
||||
return it.stream.takeSentinel(0);
|
||||
}
|
||||
|
||||
fn readByte(it: *TrieIterator) !u8 {
|
||||
var stream = it.getStream();
|
||||
const value = try stream.reader().readByte();
|
||||
it.pos += 1;
|
||||
return value;
|
||||
return it.stream.takeByte();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -243,10 +219,10 @@ fn parseTrieNode(
|
|||
const label = try it.readString();
|
||||
const off = try it.readUleb128();
|
||||
const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label });
|
||||
const curr = it.pos;
|
||||
it.pos = math.cast(usize, off) orelse return error.Overflow;
|
||||
const curr = it.stream.seek;
|
||||
it.stream.seek = math.cast(usize, off) orelse return error.Overflow;
|
||||
try self.parseTrieNode(it, allocator, arena, prefix_label);
|
||||
it.pos = curr;
|
||||
it.stream.seek = curr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,7 +233,7 @@ fn parseTrie(self: *Dylib, data: []const u8, macho_file: *MachO) !void {
|
|||
var arena = std.heap.ArenaAllocator.init(gpa);
|
||||
defer arena.deinit();
|
||||
|
||||
var it: TrieIterator = .{ .data = data };
|
||||
var it: TrieIterator = .{ .stream = .fixed(data) };
|
||||
try self.parseTrieNode(&it, gpa, arena.allocator(), "");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,31 +17,29 @@ pub const Cie = struct {
|
|||
|
||||
if (aug[0] != 'z') return; // TODO should we error out?
|
||||
|
||||
var stream = std.io.fixedBufferStream(data[9 + aug.len + 1 ..]);
|
||||
var creader = std.io.countingReader(stream.reader());
|
||||
const reader = creader.reader();
|
||||
var reader: std.Io.Reader = .fixed(data[9 + aug.len + 1 ..]);
|
||||
|
||||
_ = try leb.readUleb128(u64, reader); // code alignment factor
|
||||
_ = try leb.readUleb128(u64, reader); // data alignment factor
|
||||
_ = try leb.readUleb128(u64, reader); // return address register
|
||||
_ = try leb.readUleb128(u64, reader); // augmentation data length
|
||||
_ = try reader.takeLeb128(u64); // code alignment factor
|
||||
_ = try reader.takeLeb128(u64); // data alignment factor
|
||||
_ = try reader.takeLeb128(u64); // return address register
|
||||
_ = try reader.takeLeb128(u64); // augmentation data length
|
||||
|
||||
for (aug[1..]) |ch| switch (ch) {
|
||||
'R' => {
|
||||
const enc = try reader.readByte();
|
||||
const enc = try reader.takeByte();
|
||||
if (enc != DW_EH_PE.pcrel | DW_EH_PE.absptr) {
|
||||
@panic("unexpected pointer encoding"); // TODO error
|
||||
}
|
||||
},
|
||||
'P' => {
|
||||
const enc = try reader.readByte();
|
||||
const enc = try reader.takeByte();
|
||||
if (enc != DW_EH_PE.pcrel | DW_EH_PE.indirect | DW_EH_PE.sdata4) {
|
||||
@panic("unexpected personality pointer encoding"); // TODO error
|
||||
}
|
||||
_ = try reader.readInt(u32, .little); // personality pointer
|
||||
_ = try reader.takeInt(u32, .little); // personality pointer
|
||||
},
|
||||
'L' => {
|
||||
const enc = try reader.readByte();
|
||||
const enc = try reader.takeByte();
|
||||
switch (enc & DW_EH_PE.type_mask) {
|
||||
DW_EH_PE.sdata4 => cie.lsda_size = .p32,
|
||||
DW_EH_PE.absptr => cie.lsda_size = .p64,
|
||||
|
|
@ -163,14 +161,13 @@ pub const Fde = struct {
|
|||
|
||||
// Parse LSDA atom index if any
|
||||
if (cie.lsda_size) |lsda_size| {
|
||||
var stream = std.io.fixedBufferStream(data[24..]);
|
||||
var creader = std.io.countingReader(stream.reader());
|
||||
const reader = creader.reader();
|
||||
_ = try leb.readUleb128(u64, reader); // augmentation length
|
||||
fde.lsda_ptr_offset = @intCast(creader.bytes_read + 24);
|
||||
var reader: std.Io.Reader = .fixed(data);
|
||||
reader.seek = 24;
|
||||
_ = try reader.takeLeb128(u64); // augmentation length
|
||||
fde.lsda_ptr_offset = @intCast(reader.seek);
|
||||
const lsda_ptr = switch (lsda_size) {
|
||||
.p32 => try reader.readInt(i32, .little),
|
||||
.p64 => try reader.readInt(i64, .little),
|
||||
.p32 => try reader.takeInt(i32, .little),
|
||||
.p64 => try reader.takeInt(i64, .little),
|
||||
};
|
||||
const lsda_addr: u64 = @intCast(@as(i64, @intCast(sect.addr + fde.offset + fde.lsda_ptr_offset)) + lsda_ptr);
|
||||
fde.lsda = object.findAtom(lsda_addr) orelse {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue