| author | |
| committer | |
| log | 558bea2a76179fcc00779fdd326e5a866956fc9b |
| tree | 6070f8eb4c330ed37ef566a1e3085bbb0326e10f |
| parent | 4b948e8556b80cbc874415aa7c4bf9ac0027ffed |
7 files changed, 77 insertions(+), 174 deletions(-)
lib/std/Build/Step/CheckObject.zig+16-42| ... | @@ -1224,14 +1224,12 @@ const MachODumper = struct { | ... | @@ -1224,14 +1224,12 @@ const MachODumper = struct { |
| 1224 | } | 1224 | } |
| 1225 | 1225 | ||
| 1226 | fn parseRebaseInfo(ctx: ObjectContext, data: []const u8, rebases: *std.array_list.Managed(u64)) !void { | 1226 | fn parseRebaseInfo(ctx: ObjectContext, data: []const u8, rebases: *std.array_list.Managed(u64)) !void { |
| 1227 | var stream = std.io.fixedBufferStream(data); | 1227 | var reader: std.Io.Reader = .fixed(data); |
| 1228 | var creader = std.io.countingReader(stream.reader()); | ||
| 1229 | const reader = creader.reader(); | ||
| 1230 | 1228 | ||
| 1231 | var seg_id: ?u8 = null; | 1229 | var seg_id: ?u8 = null; |
| 1232 | var offset: u64 = 0; | 1230 | var offset: u64 = 0; |
| 1233 | while (true) { | 1231 | while (true) { |
| 1234 | const byte = reader.readByte() catch break; | 1232 | const byte = reader.takeByte() catch break; |
| 1235 | const opc = byte & macho.REBASE_OPCODE_MASK; | 1233 | const opc = byte & macho.REBASE_OPCODE_MASK; |
| 1236 | const imm = byte & macho.REBASE_IMMEDIATE_MASK; | 1234 | const imm = byte & macho.REBASE_IMMEDIATE_MASK; |
| 1237 | switch (opc) { | 1235 | switch (opc) { |
| ... | @@ -1239,17 +1237,17 @@ const MachODumper = struct { | ... | @@ -1239,17 +1237,17 @@ const MachODumper = struct { |
| 1239 | macho.REBASE_OPCODE_SET_TYPE_IMM => {}, | 1237 | macho.REBASE_OPCODE_SET_TYPE_IMM => {}, |
| 1240 | macho.REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB => { | 1238 | macho.REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB => { |
| 1241 | seg_id = imm; | 1239 | seg_id = imm; |
| 1242 | offset = try std.leb.readUleb128(u64, reader); | 1240 | offset = try reader.takeLeb128(u64); |
| 1243 | }, | 1241 | }, |
| 1244 | macho.REBASE_OPCODE_ADD_ADDR_IMM_SCALED => { | 1242 | macho.REBASE_OPCODE_ADD_ADDR_IMM_SCALED => { |
| 1245 | offset += imm * @sizeOf(u64); | 1243 | offset += imm * @sizeOf(u64); |
| 1246 | }, | 1244 | }, |
| 1247 | macho.REBASE_OPCODE_ADD_ADDR_ULEB => { | 1245 | macho.REBASE_OPCODE_ADD_ADDR_ULEB => { |
| 1248 | const addend = try std.leb.readUleb128(u64, reader); | 1246 | const addend = try reader.takeLeb128(u64); |
| 1249 | offset += addend; | 1247 | offset += addend; |
| 1250 | }, | 1248 | }, |
| 1251 | macho.REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB => { | 1249 | macho.REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB => { |
| 1252 | const addend = try std.leb.readUleb128(u64, reader); | 1250 | const addend = try reader.takeLeb128(u64); |
| 1253 | const seg = ctx.segments.items[seg_id.?]; | 1251 | const seg = ctx.segments.items[seg_id.?]; |
| 1254 | const addr = seg.vmaddr + offset; | 1252 | const addr = seg.vmaddr + offset; |
| 1255 | try rebases.append(addr); | 1253 | try rebases.append(addr); |
| ... | @@ -1266,11 +1264,11 @@ const MachODumper = struct { | ... | @@ -1266,11 +1264,11 @@ const MachODumper = struct { |
| 1266 | ntimes = imm; | 1264 | ntimes = imm; |
| 1267 | }, | 1265 | }, |
| 1268 | macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES => { | 1266 | macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES => { |
| 1269 | ntimes = try std.leb.readUleb128(u64, reader); | 1267 | ntimes = try reader.takeLeb128(u64); |
| 1270 | }, | 1268 | }, |
| 1271 | macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB => { | 1269 | macho.REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB => { |
| 1272 | ntimes = try std.leb.readUleb128(u64, reader); | 1270 | ntimes = try reader.takeLeb128(u64); |
| 1273 | skip = try std.leb.readUleb128(u64, reader); | 1271 | skip = try reader.takeLeb128(u64); |
| 1274 | }, | 1272 | }, |
| 1275 | else => unreachable, | 1273 | else => unreachable, |
| 1276 | } | 1274 | } |
| ... | @@ -1431,7 +1429,7 @@ const MachODumper = struct { | ... | @@ -1431,7 +1429,7 @@ const MachODumper = struct { |
| 1431 | defer arena.deinit(); | 1429 | defer arena.deinit(); |
| 1432 | 1430 | ||
| 1433 | var exports = std.array_list.Managed(Export).init(arena.allocator()); | 1431 | var exports = std.array_list.Managed(Export).init(arena.allocator()); |
| 1434 | var it = TrieIterator{ .data = data }; | 1432 | var it: TrieIterator = .{ .stream = .fixed(data) }; |
| 1435 | try parseTrieNode(arena.allocator(), &it, "", &exports); | 1433 | try parseTrieNode(arena.allocator(), &it, "", &exports); |
| 1436 | 1434 | ||
| 1437 | mem.sort(Export, exports.items, {}, Export.lessThan); | 1435 | mem.sort(Export, exports.items, {}, Export.lessThan); |
| ... | @@ -1462,42 +1460,18 @@ const MachODumper = struct { | ... | @@ -1462,42 +1460,18 @@ const MachODumper = struct { |
| 1462 | } | 1460 | } |
| 1463 | 1461 | ||
| 1464 | const TrieIterator = struct { | 1462 | const TrieIterator = struct { |
| 1465 | data: []const u8, | 1463 | stream: std.Io.Reader, |
| 1466 | pos: usize = 0, | ||
| 1467 | |||
| 1468 | fn getStream(it: *TrieIterator) std.io.FixedBufferStream([]const u8) { | ||
| 1469 | return std.io.fixedBufferStream(it.data[it.pos..]); | ||
| 1470 | } | ||
| 1471 | 1464 | ||
| 1472 | fn readUleb128(it: *TrieIterator) !u64 { | 1465 | fn readUleb128(it: *TrieIterator) !u64 { |
| 1473 | var stream = it.getStream(); | 1466 | return it.stream.takeLeb128(u64); |
| 1474 | var creader = std.io.countingReader(stream.reader()); | ||
| 1475 | const reader = creader.reader(); | ||
| 1476 | const value = try std.leb.readUleb128(u64, reader); | ||
| 1477 | it.pos += creader.bytes_read; | ||
| 1478 | return value; | ||
| 1479 | } | 1467 | } |
| 1480 | 1468 | ||
| 1481 | fn readString(it: *TrieIterator) ![:0]const u8 { | 1469 | fn readString(it: *TrieIterator) ![:0]const u8 { |
| 1482 | var stream = it.getStream(); | 1470 | return it.stream.takeSentinel(0); |
| 1483 | const reader = stream.reader(); | ||
| 1484 | |||
| 1485 | var count: usize = 0; | ||
| 1486 | while (true) : (count += 1) { | ||
| 1487 | const byte = try reader.readByte(); | ||
| 1488 | if (byte == 0) break; | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | const str = @as([*:0]const u8, @ptrCast(it.data.ptr + it.pos))[0..count :0]; | ||
| 1492 | it.pos += count + 1; | ||
| 1493 | return str; | ||
| 1494 | } | 1471 | } |
| 1495 | 1472 | ||
| 1496 | fn readByte(it: *TrieIterator) !u8 { | 1473 | fn readByte(it: *TrieIterator) !u8 { |
| 1497 | var stream = it.getStream(); | 1474 | return it.stream.takeByte(); |
| 1498 | const value = try stream.reader().readByte(); | ||
| 1499 | it.pos += 1; | ||
| 1500 | return value; | ||
| 1501 | } | 1475 | } |
| 1502 | }; | 1476 | }; |
| 1503 | 1477 | ||
| ... | @@ -1594,10 +1568,10 @@ const MachODumper = struct { | ... | @@ -1594,10 +1568,10 @@ const MachODumper = struct { |
| 1594 | const label = try it.readString(); | 1568 | const label = try it.readString(); |
| 1595 | const off = try it.readUleb128(); | 1569 | const off = try it.readUleb128(); |
| 1596 | const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label }); | 1570 | const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label }); |
| 1597 | const curr = it.pos; | 1571 | const curr = it.stream.seek; |
| 1598 | it.pos = off; | 1572 | it.stream.seek = off; |
| 1599 | try parseTrieNode(arena, it, prefix_label, exports); | 1573 | try parseTrieNode(arena, it, prefix_label, exports); |
| 1600 | it.pos = curr; | 1574 | it.stream.seek = curr; |
| 1601 | } | 1575 | } |
| 1602 | } | 1576 | } |
| 1603 | 1577 |
lib/std/Io.zig-5| ... | @@ -277,10 +277,6 @@ pub const AnyReader = @import("Io/DeprecatedReader.zig"); | ... | @@ -277,10 +277,6 @@ pub const AnyReader = @import("Io/DeprecatedReader.zig"); |
| 277 | pub const FixedBufferStream = @import("Io/fixed_buffer_stream.zig").FixedBufferStream; | 277 | pub const FixedBufferStream = @import("Io/fixed_buffer_stream.zig").FixedBufferStream; |
| 278 | /// Deprecated in favor of `Reader`. | 278 | /// Deprecated in favor of `Reader`. |
| 279 | pub const fixedBufferStream = @import("Io/fixed_buffer_stream.zig").fixedBufferStream; | 279 | pub const fixedBufferStream = @import("Io/fixed_buffer_stream.zig").fixedBufferStream; |
| 280 | /// Deprecated with no replacement; inefficient pattern | ||
| 281 | pub const CountingReader = @import("Io/counting_reader.zig").CountingReader; | ||
| 282 | /// Deprecated with no replacement; inefficient pattern | ||
| 283 | pub const countingReader = @import("Io/counting_reader.zig").countingReader; | ||
| 284 | 280 | ||
| 285 | pub const tty = @import("Io/tty.zig"); | 281 | pub const tty = @import("Io/tty.zig"); |
| 286 | 282 | ||
| ... | @@ -750,7 +746,6 @@ pub fn PollFiles(comptime StreamEnum: type) type { | ... | @@ -750,7 +746,6 @@ pub fn PollFiles(comptime StreamEnum: type) type { |
| 750 | test { | 746 | test { |
| 751 | _ = Reader; | 747 | _ = Reader; |
| 752 | _ = Writer; | 748 | _ = Writer; |
| 753 | _ = CountingReader; | ||
| 754 | _ = FixedBufferStream; | 749 | _ = FixedBufferStream; |
| 755 | _ = tty; | 750 | _ = tty; |
| 756 | _ = @import("Io/test.zig"); | 751 | _ = @import("Io/test.zig"); |
lib/std/Io/counting_reader.zig deleted-43| ... | @@ -1,43 +0,0 @@ | ||
| 1 | const std = @import("../std.zig"); | ||
| 2 | const io = std.io; | ||
| 3 | const testing = std.testing; | ||
| 4 | |||
| 5 | /// A Reader that counts how many bytes has been read from it. | ||
| 6 | pub fn CountingReader(comptime ReaderType: anytype) type { | ||
| 7 | return struct { | ||
| 8 | child_reader: ReaderType, | ||
| 9 | bytes_read: u64 = 0, | ||
| 10 | |||
| 11 | pub const Error = ReaderType.Error; | ||
| 12 | pub const Reader = io.GenericReader(*@This(), Error, read); | ||
| 13 | |||
| 14 | pub fn read(self: *@This(), buf: []u8) Error!usize { | ||
| 15 | const amt = try self.child_reader.read(buf); | ||
| 16 | self.bytes_read += amt; | ||
| 17 | return amt; | ||
| 18 | } | ||
| 19 | |||
| 20 | pub fn reader(self: *@This()) Reader { | ||
| 21 | return .{ .context = self }; | ||
| 22 | } | ||
| 23 | }; | ||
| 24 | } | ||
| 25 | |||
| 26 | pub fn countingReader(reader: anytype) CountingReader(@TypeOf(reader)) { | ||
| 27 | return .{ .child_reader = reader }; | ||
| 28 | } | ||
| 29 | |||
| 30 | test CountingReader { | ||
| 31 | const bytes = "yay" ** 100; | ||
| 32 | var fbs = io.fixedBufferStream(bytes); | ||
| 33 | |||
| 34 | var counting_stream = countingReader(fbs.reader()); | ||
| 35 | const stream = counting_stream.reader(); | ||
| 36 | |||
| 37 | //read and discard all bytes | ||
| 38 | while (stream.readByte()) |_| {} else |err| { | ||
| 39 | try testing.expect(err == error.EndOfStream); | ||
| 40 | } | ||
| 41 | |||
| 42 | try testing.expect(counting_stream.bytes_read == bytes.len); | ||
| 43 | } | ||
src/arch/x86_64/Disassembler.zig+23-19| ... | @@ -17,12 +17,16 @@ const Rex = encoder.Rex; | ... | @@ -17,12 +17,16 @@ const Rex = encoder.Rex; |
| 17 | 17 | ||
| 18 | pub const Error = error{ | 18 | pub const Error = error{ |
| 19 | EndOfStream, | 19 | EndOfStream, |
| 20 | /// After the TODO below is solved this will make sense. | ||
| 21 | ReadFailed, | ||
| 20 | LegacyPrefixAfterRex, | 22 | LegacyPrefixAfterRex, |
| 21 | UnknownOpcode, | 23 | UnknownOpcode, |
| 22 | Overflow, | 24 | Overflow, |
| 23 | Todo, | 25 | Todo, |
| 24 | }; | 26 | }; |
| 25 | 27 | ||
| 28 | // TODO these fields should be replaced by std.Io.Reader | ||
| 29 | |||
| 26 | code: []const u8, | 30 | code: []const u8, |
| 27 | pos: usize = 0, | 31 | pos: usize = 0, |
| 28 | 32 | ||
| ... | @@ -388,20 +392,20 @@ fn parseGpRegister(low_enc: u3, is_extended: bool, rex: Rex, bit_size: u64) Regi | ... | @@ -388,20 +392,20 @@ fn parseGpRegister(low_enc: u3, is_extended: bool, rex: Rex, bit_size: u64) Regi |
| 388 | } | 392 | } |
| 389 | 393 | ||
| 390 | fn parseImm(dis: *Disassembler, kind: Encoding.Op) !Immediate { | 394 | fn parseImm(dis: *Disassembler, kind: Encoding.Op) !Immediate { |
| 391 | var stream = std.io.fixedBufferStream(dis.code[dis.pos..]); | 395 | var reader: std.Io.Reader = .fixed(dis.code); |
| 392 | var creader = std.io.countingReader(stream.reader()); | 396 | reader.seek = dis.pos; |
| 393 | const reader = creader.reader(); | 397 | defer dis.pos = reader.seek; |
| 398 | |||
| 394 | const imm = switch (kind) { | 399 | const imm = switch (kind) { |
| 395 | .imm8s, .rel8 => Immediate.s(try reader.readInt(i8, .little)), | 400 | .imm8s, .rel8 => Immediate.s(try reader.takeInt(i8, .little)), |
| 396 | .imm16s, .rel16 => Immediate.s(try reader.readInt(i16, .little)), | 401 | .imm16s, .rel16 => Immediate.s(try reader.takeInt(i16, .little)), |
| 397 | .imm32s, .rel32 => Immediate.s(try reader.readInt(i32, .little)), | 402 | .imm32s, .rel32 => Immediate.s(try reader.takeInt(i32, .little)), |
| 398 | .imm8 => Immediate.u(try reader.readInt(u8, .little)), | 403 | .imm8 => Immediate.u(try reader.takeInt(u8, .little)), |
| 399 | .imm16 => Immediate.u(try reader.readInt(u16, .little)), | 404 | .imm16 => Immediate.u(try reader.takeInt(u16, .little)), |
| 400 | .imm32 => Immediate.u(try reader.readInt(u32, .little)), | 405 | .imm32 => Immediate.u(try reader.takeInt(u32, .little)), |
| 401 | .imm64 => Immediate.u(try reader.readInt(u64, .little)), | 406 | .imm64 => Immediate.u(try reader.takeInt(u64, .little)), |
| 402 | else => unreachable, | 407 | else => unreachable, |
| 403 | }; | 408 | }; |
| 404 | dis.pos += std.math.cast(usize, creader.bytes_read) orelse return error.Overflow; | ||
| 405 | return imm; | 409 | return imm; |
| 406 | } | 410 | } |
| 407 | 411 | ||
| ... | @@ -483,25 +487,25 @@ fn parseSibByte(dis: *Disassembler) !Sib { | ... | @@ -483,25 +487,25 @@ fn parseSibByte(dis: *Disassembler) !Sib { |
| 483 | } | 487 | } |
| 484 | 488 | ||
| 485 | fn parseDisplacement(dis: *Disassembler, modrm: ModRm, sib: ?Sib) !i32 { | 489 | fn parseDisplacement(dis: *Disassembler, modrm: ModRm, sib: ?Sib) !i32 { |
| 486 | var stream = std.io.fixedBufferStream(dis.code[dis.pos..]); | 490 | var reader: std.Io.Reader = .fixed(dis.code); |
| 487 | var creader = std.io.countingReader(stream.reader()); | 491 | reader.seek = dis.pos; |
| 488 | const reader = creader.reader(); | 492 | defer dis.pos = reader.seek; |
| 493 | |||
| 489 | const disp = disp: { | 494 | const disp = disp: { |
| 490 | if (sib) |info| { | 495 | if (sib) |info| { |
| 491 | if (info.base == 0b101 and modrm.mod == 0) { | 496 | if (info.base == 0b101 and modrm.mod == 0) { |
| 492 | break :disp try reader.readInt(i32, .little); | 497 | break :disp try reader.takeInt(i32, .little); |
| 493 | } | 498 | } |
| 494 | } | 499 | } |
| 495 | if (modrm.rip()) { | 500 | if (modrm.rip()) { |
| 496 | break :disp try reader.readInt(i32, .little); | 501 | break :disp try reader.takeInt(i32, .little); |
| 497 | } | 502 | } |
| 498 | break :disp switch (modrm.mod) { | 503 | break :disp switch (modrm.mod) { |
| 499 | 0b00 => 0, | 504 | 0b00 => 0, |
| 500 | 0b01 => try reader.readInt(i8, .little), | 505 | 0b01 => try reader.takeInt(i8, .little), |
| 501 | 0b10 => try reader.readInt(i32, .little), | 506 | 0b10 => try reader.takeInt(i32, .little), |
| 502 | 0b11 => unreachable, | 507 | 0b11 => unreachable, |
| 503 | }; | 508 | }; |
| 504 | }; | 509 | }; |
| 505 | dis.pos += std.math.cast(usize, creader.bytes_read) orelse return error.Overflow; | ||
| 506 | return disp; | 510 | return disp; |
| 507 | } | 511 | } |
src/link/MachO/Dwarf.zig+15-15| ... | @@ -273,19 +273,19 @@ pub const InfoReader = struct { | ... | @@ -273,19 +273,19 @@ pub const InfoReader = struct { |
| 273 | } | 273 | } |
| 274 | 274 | ||
| 275 | pub fn readUleb128(p: *InfoReader, comptime Type: type) !Type { | 275 | pub fn readUleb128(p: *InfoReader, comptime Type: type) !Type { |
| 276 | var stream = std.io.fixedBufferStream(p.bytes()[p.pos..]); | 276 | var reader: std.Io.Reader = .fixed(p.bytes()); |
| 277 | var creader = std.io.countingReader(stream.reader()); | 277 | reader.seek = p.pos; |
| 278 | const value: Type = try leb.readUleb128(Type, creader.reader()); | 278 | defer p.pos = reader.seek; |
| 279 | p.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow; | 279 | |
| 280 | return value; | 280 | return reader.takeLeb128(Type); |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | pub fn readIleb128(p: *InfoReader, comptime Type: type) !Type { | 283 | pub fn readIleb128(p: *InfoReader, comptime Type: type) !Type { |
| 284 | var stream = std.io.fixedBufferStream(p.bytes()[p.pos..]); | 284 | var reader: std.Io.Reader = .fixed(p.bytes()); |
| 285 | var creader = std.io.countingReader(stream.reader()); | 285 | reader.seek = p.pos; |
| 286 | const value: Type = try leb.readIleb128(Type, creader.reader()); | 286 | defer p.pos = reader.seek; |
| 287 | p.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow; | 287 | |
| 288 | return value; | 288 | return reader.takeLeb128(Type); |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | pub fn seekTo(p: *InfoReader, off: u64) !void { | 291 | pub fn seekTo(p: *InfoReader, off: u64) !void { |
| ... | @@ -340,11 +340,11 @@ pub const AbbrevReader = struct { | ... | @@ -340,11 +340,11 @@ pub const AbbrevReader = struct { |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | pub fn readUleb128(p: *AbbrevReader, comptime Type: type) !Type { | 342 | pub fn readUleb128(p: *AbbrevReader, comptime Type: type) !Type { |
| 343 | var stream = std.io.fixedBufferStream(p.bytes()[p.pos..]); | 343 | var reader: std.Io.Reader = .fixed(p.bytes()); |
| 344 | var creader = std.io.countingReader(stream.reader()); | 344 | reader.seek = p.pos; |
| 345 | const value: Type = try leb.readUleb128(Type, creader.reader()); | 345 | defer p.pos = reader.seek; |
| 346 | p.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow; | 346 | |
| 347 | return value; | 347 | return reader.takeLeb128(Type); |
| 348 | } | 348 | } |
| 349 | 349 | ||
| 350 | pub fn seekTo(p: *AbbrevReader, off: u64) !void { | 350 | pub fn seekTo(p: *AbbrevReader, off: u64) !void { |
src/link/MachO/Dylib.zig+8-32| ... | @@ -159,42 +159,18 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void { | ... | @@ -159,42 +159,18 @@ fn parseBinary(self: *Dylib, macho_file: *MachO) !void { |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | const TrieIterator = struct { | 161 | const TrieIterator = struct { |
| 162 | data: []const u8, | 162 | stream: std.Io.Reader, |
| 163 | pos: usize = 0, | ||
| 164 | |||
| 165 | fn getStream(it: *TrieIterator) std.io.FixedBufferStream([]const u8) { | ||
| 166 | return std.io.fixedBufferStream(it.data[it.pos..]); | ||
| 167 | } | ||
| 168 | 163 | ||
| 169 | fn readUleb128(it: *TrieIterator) !u64 { | 164 | fn readUleb128(it: *TrieIterator) !u64 { |
| 170 | var stream = it.getStream(); | 165 | return it.stream.takeLeb128(u64); |
| 171 | var creader = std.io.countingReader(stream.reader()); | ||
| 172 | const reader = creader.reader(); | ||
| 173 | const value = try std.leb.readUleb128(u64, reader); | ||
| 174 | it.pos += math.cast(usize, creader.bytes_read) orelse return error.Overflow; | ||
| 175 | return value; | ||
| 176 | } | 166 | } |
| 177 | 167 | ||
| 178 | fn readString(it: *TrieIterator) ![:0]const u8 { | 168 | fn readString(it: *TrieIterator) ![:0]const u8 { |
| 179 | var stream = it.getStream(); | 169 | return it.stream.takeSentinel(0); |
| 180 | const reader = stream.reader(); | ||
| 181 | |||
| 182 | var count: usize = 0; | ||
| 183 | while (true) : (count += 1) { | ||
| 184 | const byte = try reader.readByte(); | ||
| 185 | if (byte == 0) break; | ||
| 186 | } | ||
| 187 | |||
| 188 | const str = @as([*:0]const u8, @ptrCast(it.data.ptr + it.pos))[0..count :0]; | ||
| 189 | it.pos += count + 1; | ||
| 190 | return str; | ||
| 191 | } | 170 | } |
| 192 | 171 | ||
| 193 | fn readByte(it: *TrieIterator) !u8 { | 172 | fn readByte(it: *TrieIterator) !u8 { |
| 194 | var stream = it.getStream(); | 173 | return it.stream.takeByte(); |
| 195 | const value = try stream.reader().readByte(); | ||
| 196 | it.pos += 1; | ||
| 197 | return value; | ||
| 198 | } | 174 | } |
| 199 | }; | 175 | }; |
| 200 | 176 | ||
| ... | @@ -243,10 +219,10 @@ fn parseTrieNode( | ... | @@ -243,10 +219,10 @@ fn parseTrieNode( |
| 243 | const label = try it.readString(); | 219 | const label = try it.readString(); |
| 244 | const off = try it.readUleb128(); | 220 | const off = try it.readUleb128(); |
| 245 | const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label }); | 221 | const prefix_label = try std.fmt.allocPrint(arena, "{s}{s}", .{ prefix, label }); |
| 246 | const curr = it.pos; | 222 | const curr = it.stream.seek; |
| 247 | it.pos = math.cast(usize, off) orelse return error.Overflow; | 223 | it.stream.seek = math.cast(usize, off) orelse return error.Overflow; |
| 248 | try self.parseTrieNode(it, allocator, arena, prefix_label); | 224 | try self.parseTrieNode(it, allocator, arena, prefix_label); |
| 249 | it.pos = curr; | 225 | it.stream.seek = curr; |
| 250 | } | 226 | } |
| 251 | } | 227 | } |
| 252 | 228 | ||
| ... | @@ -257,7 +233,7 @@ fn parseTrie(self: *Dylib, data: []const u8, macho_file: *MachO) !void { | ... | @@ -257,7 +233,7 @@ fn parseTrie(self: *Dylib, data: []const u8, macho_file: *MachO) !void { |
| 257 | var arena = std.heap.ArenaAllocator.init(gpa); | 233 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 258 | defer arena.deinit(); | 234 | defer arena.deinit(); |
| 259 | 235 | ||
| 260 | var it: TrieIterator = .{ .data = data }; | 236 | var it: TrieIterator = .{ .stream = .fixed(data) }; |
| 261 | try self.parseTrieNode(&it, gpa, arena.allocator(), ""); | 237 | try self.parseTrieNode(&it, gpa, arena.allocator(), ""); |
| 262 | } | 238 | } |
| 263 | 239 |
src/link/MachO/eh_frame.zig+15-18| ... | @@ -17,31 +17,29 @@ pub const Cie = struct { | ... | @@ -17,31 +17,29 @@ pub const Cie = struct { |
| 17 | 17 | ||
| 18 | if (aug[0] != 'z') return; // TODO should we error out? | 18 | if (aug[0] != 'z') return; // TODO should we error out? |
| 19 | 19 | ||
| 20 | var stream = std.io.fixedBufferStream(data[9 + aug.len + 1 ..]); | 20 | var reader: std.Io.Reader = .fixed(data[9 + aug.len + 1 ..]); |
| 21 | var creader = std.io.countingReader(stream.reader()); | ||
| 22 | const reader = creader.reader(); | ||
| 23 | 21 | ||
| 24 | _ = try leb.readUleb128(u64, reader); // code alignment factor | 22 | _ = try reader.takeLeb128(u64); // code alignment factor |
| 25 | _ = try leb.readUleb128(u64, reader); // data alignment factor | 23 | _ = try reader.takeLeb128(u64); // data alignment factor |
| 26 | _ = try leb.readUleb128(u64, reader); // return address register | 24 | _ = try reader.takeLeb128(u64); // return address register |
| 27 | _ = try leb.readUleb128(u64, reader); // augmentation data length | 25 | _ = try reader.takeLeb128(u64); // augmentation data length |
| 28 | 26 | ||
| 29 | for (aug[1..]) |ch| switch (ch) { | 27 | for (aug[1..]) |ch| switch (ch) { |
| 30 | 'R' => { | 28 | 'R' => { |
| 31 | const enc = try reader.readByte(); | 29 | const enc = try reader.takeByte(); |
| 32 | if (enc != DW_EH_PE.pcrel | DW_EH_PE.absptr) { | 30 | if (enc != DW_EH_PE.pcrel | DW_EH_PE.absptr) { |
| 33 | @panic("unexpected pointer encoding"); // TODO error | 31 | @panic("unexpected pointer encoding"); // TODO error |
| 34 | } | 32 | } |
| 35 | }, | 33 | }, |
| 36 | 'P' => { | 34 | 'P' => { |
| 37 | const enc = try reader.readByte(); | 35 | const enc = try reader.takeByte(); |
| 38 | if (enc != DW_EH_PE.pcrel | DW_EH_PE.indirect | DW_EH_PE.sdata4) { | 36 | if (enc != DW_EH_PE.pcrel | DW_EH_PE.indirect | DW_EH_PE.sdata4) { |
| 39 | @panic("unexpected personality pointer encoding"); // TODO error | 37 | @panic("unexpected personality pointer encoding"); // TODO error |
| 40 | } | 38 | } |
| 41 | _ = try reader.readInt(u32, .little); // personality pointer | 39 | _ = try reader.takeInt(u32, .little); // personality pointer |
| 42 | }, | 40 | }, |
| 43 | 'L' => { | 41 | 'L' => { |
| 44 | const enc = try reader.readByte(); | 42 | const enc = try reader.takeByte(); |
| 45 | switch (enc & DW_EH_PE.type_mask) { | 43 | switch (enc & DW_EH_PE.type_mask) { |
| 46 | DW_EH_PE.sdata4 => cie.lsda_size = .p32, | 44 | DW_EH_PE.sdata4 => cie.lsda_size = .p32, |
| 47 | DW_EH_PE.absptr => cie.lsda_size = .p64, | 45 | DW_EH_PE.absptr => cie.lsda_size = .p64, |
| ... | @@ -163,14 +161,13 @@ pub const Fde = struct { | ... | @@ -163,14 +161,13 @@ pub const Fde = struct { |
| 163 | 161 | ||
| 164 | // Parse LSDA atom index if any | 162 | // Parse LSDA atom index if any |
| 165 | if (cie.lsda_size) |lsda_size| { | 163 | if (cie.lsda_size) |lsda_size| { |
| 166 | var stream = std.io.fixedBufferStream(data[24..]); | 164 | var reader: std.Io.Reader = .fixed(data); |
| 167 | var creader = std.io.countingReader(stream.reader()); | 165 | reader.seek = 24; |
| 168 | const reader = creader.reader(); | 166 | _ = try reader.takeLeb128(u64); // augmentation length |
| 169 | _ = try leb.readUleb128(u64, reader); // augmentation length | 167 | fde.lsda_ptr_offset = @intCast(reader.seek); |
| 170 | fde.lsda_ptr_offset = @intCast(creader.bytes_read + 24); | ||
| 171 | const lsda_ptr = switch (lsda_size) { | 168 | const lsda_ptr = switch (lsda_size) { |
| 172 | .p32 => try reader.readInt(i32, .little), | 169 | .p32 => try reader.takeInt(i32, .little), |
| 173 | .p64 => try reader.readInt(i64, .little), | 170 | .p64 => try reader.takeInt(i64, .little), |
| 174 | }; | 171 | }; |
| 175 | const lsda_addr: u64 = @intCast(@as(i64, @intCast(sect.addr + fde.offset + fde.lsda_ptr_offset)) + lsda_ptr); | 172 | const lsda_addr: u64 = @intCast(@as(i64, @intCast(sect.addr + fde.offset + fde.lsda_ptr_offset)) + lsda_ptr); |
| 176 | fde.lsda = object.findAtom(lsda_addr) orelse { | 173 | fde.lsda = object.findAtom(lsda_addr) orelse { |