mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
Merge pull request #24742 from ziglang/CountingWriter
std.Io: delete CountingWriter
This commit is contained in:
commit
d2f7792039
11 changed files with 76 additions and 119 deletions
|
|
@ -665,19 +665,16 @@ const ResourceTree = struct {
|
||||||
pub fn writeCoff(
|
pub fn writeCoff(
|
||||||
self: *const ResourceTree,
|
self: *const ResourceTree,
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
writer: anytype,
|
w: anytype,
|
||||||
resources_in_data_order: []const Resource,
|
resources_in_data_order: []const Resource,
|
||||||
lengths: Lengths,
|
lengths: Lengths,
|
||||||
coff_string_table: *StringTable,
|
coff_string_table: *StringTable,
|
||||||
) ![]const std.coff.Symbol {
|
) ![]const std.coff.Symbol {
|
||||||
if (self.type_to_name_map.count() == 0) {
|
if (self.type_to_name_map.count() == 0) {
|
||||||
try writer.writeByteNTimes(0, 16);
|
try w.writeByteNTimes(0, 16);
|
||||||
return &.{};
|
return &.{};
|
||||||
}
|
}
|
||||||
|
|
||||||
var counting_writer = std.io.countingWriter(writer);
|
|
||||||
const w = counting_writer.writer();
|
|
||||||
|
|
||||||
var level2_list: std.ArrayListUnmanaged(*const NameToLanguageMap) = .empty;
|
var level2_list: std.ArrayListUnmanaged(*const NameToLanguageMap) = .empty;
|
||||||
defer level2_list.deinit(allocator);
|
defer level2_list.deinit(allocator);
|
||||||
|
|
||||||
|
|
@ -735,7 +732,6 @@ const ResourceTree = struct {
|
||||||
try level2_list.append(allocator, name_to_lang_map);
|
try level2_list.append(allocator, name_to_lang_map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.debug.assert(counting_writer.bytes_written == level2_start);
|
|
||||||
|
|
||||||
const level3_start = level2_start + lengths.level2;
|
const level3_start = level2_start + lengths.level2;
|
||||||
var level3_address = level3_start;
|
var level3_address = level3_start;
|
||||||
|
|
@ -771,7 +767,6 @@ const ResourceTree = struct {
|
||||||
try level3_list.append(allocator, lang_to_resources_map);
|
try level3_list.append(allocator, lang_to_resources_map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.debug.assert(counting_writer.bytes_written == level3_start);
|
|
||||||
|
|
||||||
var reloc_addresses = try allocator.alloc(u32, resources_in_data_order.len);
|
var reloc_addresses = try allocator.alloc(u32, resources_in_data_order.len);
|
||||||
defer allocator.free(reloc_addresses);
|
defer allocator.free(reloc_addresses);
|
||||||
|
|
@ -813,7 +808,6 @@ const ResourceTree = struct {
|
||||||
try resources_list.append(allocator, reloc_resource);
|
try resources_list.append(allocator, reloc_resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std.debug.assert(counting_writer.bytes_written == data_entries_start);
|
|
||||||
|
|
||||||
for (resources_list.items, 0..) |reloc_resource, i| {
|
for (resources_list.items, 0..) |reloc_resource, i| {
|
||||||
// TODO: This logic works but is convoluted, would be good to clean this up
|
// TODO: This logic works but is convoluted, would be good to clean this up
|
||||||
|
|
@ -827,7 +821,6 @@ const ResourceTree = struct {
|
||||||
};
|
};
|
||||||
try w.writeStructEndian(data_entry, .little);
|
try w.writeStructEndian(data_entry, .little);
|
||||||
}
|
}
|
||||||
std.debug.assert(counting_writer.bytes_written == strings_start);
|
|
||||||
|
|
||||||
for (self.rsrc_string_table.keys()) |v| {
|
for (self.rsrc_string_table.keys()) |v| {
|
||||||
const str = v.name;
|
const str = v.name;
|
||||||
|
|
|
||||||
|
|
@ -432,10 +432,6 @@ pub const FixedBufferStream = @import("Io/fixed_buffer_stream.zig").FixedBufferS
|
||||||
/// Deprecated in favor of `Reader`.
|
/// Deprecated in favor of `Reader`.
|
||||||
pub const fixedBufferStream = @import("Io/fixed_buffer_stream.zig").fixedBufferStream;
|
pub const fixedBufferStream = @import("Io/fixed_buffer_stream.zig").fixedBufferStream;
|
||||||
/// Deprecated with no replacement; inefficient pattern
|
/// Deprecated with no replacement; inefficient pattern
|
||||||
pub const CountingWriter = @import("Io/counting_writer.zig").CountingWriter;
|
|
||||||
/// Deprecated with no replacement; inefficient pattern
|
|
||||||
pub const countingWriter = @import("Io/counting_writer.zig").countingWriter;
|
|
||||||
/// Deprecated with no replacement; inefficient pattern
|
|
||||||
pub const CountingReader = @import("Io/counting_reader.zig").CountingReader;
|
pub const CountingReader = @import("Io/counting_reader.zig").CountingReader;
|
||||||
/// Deprecated with no replacement; inefficient pattern
|
/// Deprecated with no replacement; inefficient pattern
|
||||||
pub const countingReader = @import("Io/counting_reader.zig").countingReader;
|
pub const countingReader = @import("Io/counting_reader.zig").countingReader;
|
||||||
|
|
@ -917,7 +913,6 @@ test {
|
||||||
_ = Reader;
|
_ = Reader;
|
||||||
_ = Writer;
|
_ = Writer;
|
||||||
_ = BufferedWriter;
|
_ = BufferedWriter;
|
||||||
_ = CountingWriter;
|
|
||||||
_ = CountingReader;
|
_ = CountingReader;
|
||||||
_ = FixedBufferStream;
|
_ = FixedBufferStream;
|
||||||
_ = tty;
|
_ = tty;
|
||||||
|
|
|
||||||
|
|
@ -2239,6 +2239,11 @@ pub const Discarding = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Includes buffered data (no need to flush).
|
||||||
|
pub fn fullCount(d: *const Discarding) u64 {
|
||||||
|
return d.count + d.writer.end;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn drain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
|
pub fn drain(w: *Writer, data: []const []const u8, splat: usize) Error!usize {
|
||||||
const d: *Discarding = @alignCast(@fieldParentPtr("writer", w));
|
const d: *Discarding = @alignCast(@fieldParentPtr("writer", w));
|
||||||
const slice = data[0 .. data.len - 1];
|
const slice = data[0 .. data.len - 1];
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
const std = @import("../std.zig");
|
|
||||||
const io = std.io;
|
|
||||||
const testing = std.testing;
|
|
||||||
|
|
||||||
/// A Writer that counts how many bytes has been written to it.
|
|
||||||
pub fn CountingWriter(comptime WriterType: type) type {
|
|
||||||
return struct {
|
|
||||||
bytes_written: u64,
|
|
||||||
child_stream: WriterType,
|
|
||||||
|
|
||||||
pub const Error = WriterType.Error;
|
|
||||||
pub const Writer = io.GenericWriter(*Self, Error, write);
|
|
||||||
|
|
||||||
const Self = @This();
|
|
||||||
|
|
||||||
pub fn write(self: *Self, bytes: []const u8) Error!usize {
|
|
||||||
const amt = try self.child_stream.write(bytes);
|
|
||||||
self.bytes_written += amt;
|
|
||||||
return amt;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn writer(self: *Self) Writer {
|
|
||||||
return .{ .context = self };
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn countingWriter(child_stream: anytype) CountingWriter(@TypeOf(child_stream)) {
|
|
||||||
return .{ .bytes_written = 0, .child_stream = child_stream };
|
|
||||||
}
|
|
||||||
|
|
||||||
test CountingWriter {
|
|
||||||
var counting_stream = countingWriter(std.io.null_writer);
|
|
||||||
const stream = counting_stream.writer();
|
|
||||||
|
|
||||||
const bytes = "yay" ** 100;
|
|
||||||
stream.writeAll(bytes) catch unreachable;
|
|
||||||
try testing.expect(counting_stream.bytes_written == bytes.len);
|
|
||||||
}
|
|
||||||
|
|
@ -5,6 +5,7 @@ const fmt = std.fmt;
|
||||||
const io = std.io;
|
const io = std.io;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const meta = std.meta;
|
const meta = std.meta;
|
||||||
|
const Writer = std.Io.Writer;
|
||||||
|
|
||||||
const fields_delimiter = "$";
|
const fields_delimiter = "$";
|
||||||
const fields_delimiter_scalar = '$';
|
const fields_delimiter_scalar = '$';
|
||||||
|
|
@ -188,19 +189,20 @@ pub fn deserialize(comptime HashResult: type, str: []const u8) Error!HashResult
|
||||||
///
|
///
|
||||||
/// `params` can also include any additional parameters.
|
/// `params` can also include any additional parameters.
|
||||||
pub fn serialize(params: anytype, str: []u8) Error![]const u8 {
|
pub fn serialize(params: anytype, str: []u8) Error![]const u8 {
|
||||||
var buf = io.fixedBufferStream(str);
|
var w: Writer = .fixed(str);
|
||||||
try serializeTo(params, buf.writer());
|
serializeTo(params, &w) catch return error.NoSpaceLeft;
|
||||||
return buf.getWritten();
|
return w.buffered();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the number of bytes required to serialize `params`
|
/// Compute the number of bytes required to serialize `params`
|
||||||
pub fn calcSize(params: anytype) usize {
|
pub fn calcSize(params: anytype) usize {
|
||||||
var buf = io.countingWriter(io.null_writer);
|
var trash: [128]u8 = undefined;
|
||||||
serializeTo(params, buf.writer()) catch unreachable;
|
var d: Writer.Discarding = .init(&trash);
|
||||||
return @as(usize, @intCast(buf.bytes_written));
|
serializeTo(params, &d.writer) catch unreachable;
|
||||||
|
return @intCast(d.fullCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serializeTo(params: anytype, out: anytype) !void {
|
fn serializeTo(params: anytype, out: *std.Io.Writer) !void {
|
||||||
const HashResult = @TypeOf(params);
|
const HashResult = @TypeOf(params);
|
||||||
|
|
||||||
if (@hasField(HashResult, version_param_name)) {
|
if (@hasField(HashResult, version_param_name)) {
|
||||||
|
|
|
||||||
|
|
@ -311,9 +311,10 @@ const crypt_format = struct {
|
||||||
|
|
||||||
/// Compute the number of bytes required to serialize `params`
|
/// Compute the number of bytes required to serialize `params`
|
||||||
pub fn calcSize(params: anytype) usize {
|
pub fn calcSize(params: anytype) usize {
|
||||||
var buf = io.countingWriter(io.null_writer);
|
var trash: [128]u8 = undefined;
|
||||||
serializeTo(params, buf.writer()) catch unreachable;
|
var d: std.Io.Writer.Discarding = .init(&trash);
|
||||||
return @as(usize, @intCast(buf.bytes_written));
|
serializeTo(params, &d) catch unreachable;
|
||||||
|
return @intCast(d.fullCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serializeTo(params: anytype, out: anytype) !void {
|
fn serializeTo(params: anytype, out: anytype) !void {
|
||||||
|
|
|
||||||
|
|
@ -1204,11 +1204,10 @@ const TestEncode = struct {
|
||||||
mnemonic: Instruction.Mnemonic,
|
mnemonic: Instruction.Mnemonic,
|
||||||
ops: []const Instruction.Operand,
|
ops: []const Instruction.Operand,
|
||||||
) !void {
|
) !void {
|
||||||
var stream = std.io.fixedBufferStream(&enc.buffer);
|
var writer: std.Io.Writer = .fixed(&enc.buffer);
|
||||||
var count_writer = std.io.countingWriter(stream.writer());
|
|
||||||
const inst: Instruction = try .new(.none, mnemonic, ops);
|
const inst: Instruction = try .new(.none, mnemonic, ops);
|
||||||
try inst.encode(count_writer.writer(), .{});
|
try inst.encode(&writer, .{});
|
||||||
enc.index = count_writer.bytes_written;
|
enc.index = writer.bufferedLen();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn code(enc: TestEncode) []const u8 {
|
fn code(enc: TestEncode) []const u8 {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
gpa: std.mem.Allocator,
|
gpa: Allocator,
|
||||||
bin_file: *link.File,
|
bin_file: *link.File,
|
||||||
format: DW.Format,
|
format: DW.Format,
|
||||||
endian: std.builtin.Endian,
|
endian: std.builtin.Endian,
|
||||||
|
|
@ -21,6 +21,7 @@ debug_rnglists: DebugRngLists,
|
||||||
debug_str: StringSection,
|
debug_str: StringSection,
|
||||||
|
|
||||||
pub const UpdateError = error{
|
pub const UpdateError = error{
|
||||||
|
WriteFailed,
|
||||||
ReinterpretDeclRef,
|
ReinterpretDeclRef,
|
||||||
Unimplemented,
|
Unimplemented,
|
||||||
EndOfStream,
|
EndOfStream,
|
||||||
|
|
@ -50,7 +51,7 @@ const ModInfo = struct {
|
||||||
dirs: std.AutoArrayHashMapUnmanaged(Unit.Index, void),
|
dirs: std.AutoArrayHashMapUnmanaged(Unit.Index, void),
|
||||||
files: std.AutoArrayHashMapUnmanaged(Zcu.File.Index, void),
|
files: std.AutoArrayHashMapUnmanaged(Zcu.File.Index, void),
|
||||||
|
|
||||||
fn deinit(mod_info: *ModInfo, gpa: std.mem.Allocator) void {
|
fn deinit(mod_info: *ModInfo, gpa: Allocator) void {
|
||||||
mod_info.dirs.deinit(gpa);
|
mod_info.dirs.deinit(gpa);
|
||||||
mod_info.files.deinit(gpa);
|
mod_info.files.deinit(gpa);
|
||||||
mod_info.* = undefined;
|
mod_info.* = undefined;
|
||||||
|
|
@ -220,7 +221,7 @@ const StringSection = struct {
|
||||||
.section = Section.init,
|
.section = Section.init,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn deinit(str_sec: *StringSection, gpa: std.mem.Allocator) void {
|
fn deinit(str_sec: *StringSection, gpa: Allocator) void {
|
||||||
str_sec.contents.deinit(gpa);
|
str_sec.contents.deinit(gpa);
|
||||||
str_sec.map.deinit(gpa);
|
str_sec.map.deinit(gpa);
|
||||||
str_sec.section.deinit(gpa);
|
str_sec.section.deinit(gpa);
|
||||||
|
|
@ -297,7 +298,7 @@ pub const Section = struct {
|
||||||
.len = 0,
|
.len = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn deinit(sec: *Section, gpa: std.mem.Allocator) void {
|
fn deinit(sec: *Section, gpa: Allocator) void {
|
||||||
for (sec.units.items) |*unit| unit.deinit(gpa);
|
for (sec.units.items) |*unit| unit.deinit(gpa);
|
||||||
sec.units.deinit(gpa);
|
sec.units.deinit(gpa);
|
||||||
sec.* = undefined;
|
sec.* = undefined;
|
||||||
|
|
@ -357,7 +358,7 @@ pub const Section = struct {
|
||||||
if (sec.last == unit.toOptional()) sec.last = unit_ptr.prev;
|
if (sec.last == unit.toOptional()) sec.last = unit_ptr.prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn popUnit(sec: *Section, gpa: std.mem.Allocator) void {
|
fn popUnit(sec: *Section, gpa: Allocator) void {
|
||||||
const unit_index: Unit.Index = @enumFromInt(sec.units.items.len - 1);
|
const unit_index: Unit.Index = @enumFromInt(sec.units.items.len - 1);
|
||||||
sec.unlinkUnit(unit_index);
|
sec.unlinkUnit(unit_index);
|
||||||
var unit = sec.units.pop().?;
|
var unit = sec.units.pop().?;
|
||||||
|
|
@ -518,7 +519,7 @@ const Unit = struct {
|
||||||
unit.cross_section_relocs.clearRetainingCapacity();
|
unit.cross_section_relocs.clearRetainingCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deinit(unit: *Unit, gpa: std.mem.Allocator) void {
|
fn deinit(unit: *Unit, gpa: Allocator) void {
|
||||||
for (unit.entries.items) |*entry| entry.deinit(gpa);
|
for (unit.entries.items) |*entry| entry.deinit(gpa);
|
||||||
unit.entries.deinit(gpa);
|
unit.entries.deinit(gpa);
|
||||||
unit.cross_unit_relocs.deinit(gpa);
|
unit.cross_unit_relocs.deinit(gpa);
|
||||||
|
|
@ -526,7 +527,7 @@ const Unit = struct {
|
||||||
unit.* = undefined;
|
unit.* = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addEntry(unit: *Unit, gpa: std.mem.Allocator) std.mem.Allocator.Error!Entry.Index {
|
fn addEntry(unit: *Unit, gpa: Allocator) Allocator.Error!Entry.Index {
|
||||||
if (unit.free.unwrap()) |entry| {
|
if (unit.free.unwrap()) |entry| {
|
||||||
const entry_ptr = unit.getEntry(entry);
|
const entry_ptr = unit.getEntry(entry);
|
||||||
unit.free = entry_ptr.next;
|
unit.free = entry_ptr.next;
|
||||||
|
|
@ -780,7 +781,7 @@ const Entry = struct {
|
||||||
entry.external_relocs.clearRetainingCapacity();
|
entry.external_relocs.clearRetainingCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deinit(entry: *Entry, gpa: std.mem.Allocator) void {
|
fn deinit(entry: *Entry, gpa: Allocator) void {
|
||||||
entry.cross_entry_relocs.deinit(gpa);
|
entry.cross_entry_relocs.deinit(gpa);
|
||||||
entry.cross_unit_relocs.deinit(gpa);
|
entry.cross_unit_relocs.deinit(gpa);
|
||||||
entry.cross_section_relocs.deinit(gpa);
|
entry.cross_section_relocs.deinit(gpa);
|
||||||
|
|
@ -1133,7 +1134,7 @@ pub const Loc = union(enum) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn writeReg(reg: u32, op0: u8, opx: u8, writer: anytype) @TypeOf(writer).Error!void {
|
fn writeReg(reg: u32, op0: u8, opx: u8, writer: anytype) !void {
|
||||||
if (std.math.cast(u5, reg)) |small_reg| {
|
if (std.math.cast(u5, reg)) |small_reg| {
|
||||||
try writer.writeByte(op0 + small_reg);
|
try writer.writeByte(op0 + small_reg);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1142,7 +1143,7 @@ pub const Loc = union(enum) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(loc: Loc, adapter: anytype) UpdateError!void {
|
fn write(loc: Loc, adapter: anytype) !void {
|
||||||
const writer = adapter.writer();
|
const writer = adapter.writer();
|
||||||
switch (loc) {
|
switch (loc) {
|
||||||
.empty => {},
|
.empty => {},
|
||||||
|
|
@ -1712,15 +1713,15 @@ pub const WipNav = struct {
|
||||||
wip_nav.func = func;
|
wip_nav.func = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn externalReloc(wip_nav: *WipNav, sec: *Section, reloc: ExternalReloc) std.mem.Allocator.Error!void {
|
fn externalReloc(wip_nav: *WipNav, sec: *Section, reloc: ExternalReloc) Allocator.Error!void {
|
||||||
try sec.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(wip_nav.dwarf.gpa, reloc);
|
try sec.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.append(wip_nav.dwarf.gpa, reloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn infoExternalReloc(wip_nav: *WipNav, reloc: ExternalReloc) std.mem.Allocator.Error!void {
|
pub fn infoExternalReloc(wip_nav: *WipNav, reloc: ExternalReloc) Allocator.Error!void {
|
||||||
try wip_nav.externalReloc(&wip_nav.dwarf.debug_info.section, reloc);
|
try wip_nav.externalReloc(&wip_nav.dwarf.debug_info.section, reloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn frameExternalReloc(wip_nav: *WipNav, reloc: ExternalReloc) std.mem.Allocator.Error!void {
|
fn frameExternalReloc(wip_nav: *WipNav, reloc: ExternalReloc) Allocator.Error!void {
|
||||||
try wip_nav.externalReloc(&wip_nav.dwarf.debug_frame.section, reloc);
|
try wip_nav.externalReloc(&wip_nav.dwarf.debug_frame.section, reloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1768,33 +1769,33 @@ pub const WipNav = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ExprLocCounter = struct {
|
const ExprLocCounter = struct {
|
||||||
const Stream = std.io.CountingWriter(std.io.NullWriter);
|
stream: Writer.Discarding,
|
||||||
stream: Stream,
|
|
||||||
section_offset_bytes: u32,
|
section_offset_bytes: u32,
|
||||||
address_size: AddressSize,
|
address_size: AddressSize,
|
||||||
fn init(dwarf: *Dwarf) ExprLocCounter {
|
fn init(dwarf: *Dwarf, trash_buffer: []u8) ExprLocCounter {
|
||||||
return .{
|
return .{
|
||||||
.stream = std.io.countingWriter(std.io.null_writer),
|
.stream = .init(trash_buffer),
|
||||||
.section_offset_bytes = dwarf.sectionOffsetBytes(),
|
.section_offset_bytes = dwarf.sectionOffsetBytes(),
|
||||||
.address_size = dwarf.address_size,
|
.address_size = dwarf.address_size,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
fn writer(counter: *ExprLocCounter) Stream.Writer {
|
fn writer(counter: *ExprLocCounter) *Writer {
|
||||||
return counter.stream.writer();
|
return &counter.stream.writer;
|
||||||
}
|
}
|
||||||
fn endian(_: ExprLocCounter) std.builtin.Endian {
|
fn endian(_: ExprLocCounter) std.builtin.Endian {
|
||||||
return @import("builtin").cpu.arch.endian();
|
return @import("builtin").cpu.arch.endian();
|
||||||
}
|
}
|
||||||
fn addrSym(counter: *ExprLocCounter, _: u32) error{}!void {
|
fn addrSym(counter: *ExprLocCounter, _: u32) error{}!void {
|
||||||
counter.stream.bytes_written += @intFromEnum(counter.address_size);
|
counter.stream.count += @intFromEnum(counter.address_size);
|
||||||
}
|
}
|
||||||
fn infoEntry(counter: *ExprLocCounter, _: Unit.Index, _: Entry.Index) error{}!void {
|
fn infoEntry(counter: *ExprLocCounter, _: Unit.Index, _: Entry.Index) error{}!void {
|
||||||
counter.stream.bytes_written += counter.section_offset_bytes;
|
counter.stream.count += counter.section_offset_bytes;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn infoExprLoc(wip_nav: *WipNav, loc: Loc) UpdateError!void {
|
fn infoExprLoc(wip_nav: *WipNav, loc: Loc) UpdateError!void {
|
||||||
var counter: ExprLocCounter = .init(wip_nav.dwarf);
|
var trash_buffer: [64]u8 = undefined;
|
||||||
|
var counter: ExprLocCounter = .init(wip_nav.dwarf, &trash_buffer);
|
||||||
try loc.write(&counter);
|
try loc.write(&counter);
|
||||||
|
|
||||||
const adapter: struct {
|
const adapter: struct {
|
||||||
|
|
@ -1812,7 +1813,7 @@ pub const WipNav = struct {
|
||||||
try ctx.wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
|
try ctx.wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
|
||||||
}
|
}
|
||||||
} = .{ .wip_nav = wip_nav };
|
} = .{ .wip_nav = wip_nav };
|
||||||
try uleb128(adapter.writer(), counter.stream.bytes_written);
|
try uleb128(adapter.writer(), counter.stream.fullCount());
|
||||||
try loc.write(adapter);
|
try loc.write(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1826,7 +1827,8 @@ pub const WipNav = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn frameExprLoc(wip_nav: *WipNav, loc: Loc) UpdateError!void {
|
fn frameExprLoc(wip_nav: *WipNav, loc: Loc) UpdateError!void {
|
||||||
var counter: ExprLocCounter = .init(wip_nav.dwarf);
|
var trash_buffer: [64]u8 = undefined;
|
||||||
|
var counter: ExprLocCounter = .init(wip_nav.dwarf, &trash_buffer);
|
||||||
try loc.write(&counter);
|
try loc.write(&counter);
|
||||||
|
|
||||||
const adapter: struct {
|
const adapter: struct {
|
||||||
|
|
@ -1844,7 +1846,7 @@ pub const WipNav = struct {
|
||||||
try ctx.wip_nav.sectionOffset(.debug_frame, .debug_info, unit, entry, 0);
|
try ctx.wip_nav.sectionOffset(.debug_frame, .debug_info, unit, entry, 0);
|
||||||
}
|
}
|
||||||
} = .{ .wip_nav = wip_nav };
|
} = .{ .wip_nav = wip_nav };
|
||||||
try uleb128(adapter.writer(), counter.stream.bytes_written);
|
try uleb128(adapter.writer(), counter.stream.fullCount());
|
||||||
try loc.write(adapter);
|
try loc.write(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1922,7 +1924,7 @@ pub const WipNav = struct {
|
||||||
try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
|
try wip_nav.infoSectionOffset(.debug_info, unit, entry, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refForward(wip_nav: *WipNav) std.mem.Allocator.Error!u32 {
|
fn refForward(wip_nav: *WipNav) Allocator.Error!u32 {
|
||||||
const dwarf = wip_nav.dwarf;
|
const dwarf = wip_nav.dwarf;
|
||||||
const cross_entry_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_entry_relocs;
|
const cross_entry_relocs = &dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).cross_entry_relocs;
|
||||||
const reloc_index: u32 = @intCast(cross_entry_relocs.items.len);
|
const reloc_index: u32 = @intCast(cross_entry_relocs.items.len);
|
||||||
|
|
@ -6022,14 +6024,14 @@ fn sectionOffsetBytes(dwarf: *Dwarf) u32 {
|
||||||
|
|
||||||
fn uleb128Bytes(value: anytype) u32 {
|
fn uleb128Bytes(value: anytype) u32 {
|
||||||
var trash_buffer: [64]u8 = undefined;
|
var trash_buffer: [64]u8 = undefined;
|
||||||
var d: std.Io.Writer.Discarding = .init(&trash_buffer);
|
var d: Writer.Discarding = .init(&trash_buffer);
|
||||||
d.writer.writeUleb128(value) catch unreachable;
|
d.writer.writeUleb128(value) catch unreachable;
|
||||||
return @intCast(d.count + d.writer.end);
|
return @intCast(d.count + d.writer.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sleb128Bytes(value: anytype) u32 {
|
fn sleb128Bytes(value: anytype) u32 {
|
||||||
var trash_buffer: [64]u8 = undefined;
|
var trash_buffer: [64]u8 = undefined;
|
||||||
var d: std.Io.Writer.Discarding = .init(&trash_buffer);
|
var d: Writer.Discarding = .init(&trash_buffer);
|
||||||
d.writer.writeSleb128(value) catch unreachable;
|
d.writer.writeSleb128(value) catch unreachable;
|
||||||
return @intCast(d.count + d.writer.end);
|
return @intCast(d.count + d.writer.end);
|
||||||
}
|
}
|
||||||
|
|
@ -6057,3 +6059,5 @@ const sleb128 = std.leb.writeIleb128;
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const target_info = @import("../target.zig");
|
const target_info = @import("../target.zig");
|
||||||
const uleb128 = std.leb.writeUleb128;
|
const uleb128 = std.leb.writeUleb128;
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
const Writer = std.Io.Writer;
|
||||||
|
|
|
||||||
|
|
@ -3152,10 +3152,11 @@ fn writeSyntheticSections(self: *Elf) !void {
|
||||||
|
|
||||||
if (self.section_indexes.gnu_hash) |shndx| {
|
if (self.section_indexes.gnu_hash) |shndx| {
|
||||||
const shdr = slice.items(.shdr)[shndx];
|
const shdr = slice.items(.shdr)[shndx];
|
||||||
var buffer = try std.ArrayList(u8).initCapacity(gpa, self.gnu_hash.size());
|
var aw: std.Io.Writer.Allocating = .init(gpa);
|
||||||
defer buffer.deinit();
|
try aw.ensureUnusedCapacity(self.gnu_hash.size());
|
||||||
try self.gnu_hash.write(self, buffer.writer());
|
defer aw.deinit();
|
||||||
try self.pwriteAll(buffer.items, shdr.sh_offset);
|
try self.gnu_hash.write(self, &aw.writer);
|
||||||
|
try self.pwriteAll(aw.getWritten(), shdr.sh_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.section_indexes.versym) |shndx| {
|
if (self.section_indexes.versym) |shndx| {
|
||||||
|
|
|
||||||
|
|
@ -1237,17 +1237,14 @@ pub const GnuHashSection = struct {
|
||||||
return header_size + hash.num_bloom * 8 + hash.num_buckets * 4 + hash.num_exports * 4;
|
return header_size + hash.num_bloom * 8 + hash.num_buckets * 4 + hash.num_exports * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write(hash: GnuHashSection, elf_file: *Elf, writer: anytype) !void {
|
pub fn write(hash: GnuHashSection, elf_file: *Elf, writer: *std.Io.Writer) !void {
|
||||||
const exports = getExports(elf_file);
|
const exports = getExports(elf_file);
|
||||||
const export_off = elf_file.dynsym.count() - hash.num_exports;
|
const export_off = elf_file.dynsym.count() - hash.num_exports;
|
||||||
|
|
||||||
var counting = std.io.countingWriter(writer);
|
try writer.writeInt(u32, hash.num_buckets, .little);
|
||||||
const cwriter = counting.writer();
|
try writer.writeInt(u32, export_off, .little);
|
||||||
|
try writer.writeInt(u32, hash.num_bloom, .little);
|
||||||
try cwriter.writeInt(u32, hash.num_buckets, .little);
|
try writer.writeInt(u32, bloom_shift, .little);
|
||||||
try cwriter.writeInt(u32, export_off, .little);
|
|
||||||
try cwriter.writeInt(u32, hash.num_bloom, .little);
|
|
||||||
try cwriter.writeInt(u32, bloom_shift, .little);
|
|
||||||
|
|
||||||
const comp = elf_file.base.comp;
|
const comp = elf_file.base.comp;
|
||||||
const gpa = comp.gpa;
|
const gpa = comp.gpa;
|
||||||
|
|
@ -1271,7 +1268,7 @@ pub const GnuHashSection = struct {
|
||||||
bloom[idx] |= @as(u64, 1) << @as(u6, @intCast((h >> bloom_shift) % 64));
|
bloom[idx] |= @as(u64, 1) << @as(u6, @intCast((h >> bloom_shift) % 64));
|
||||||
}
|
}
|
||||||
|
|
||||||
try cwriter.writeAll(mem.sliceAsBytes(bloom));
|
try writer.writeAll(mem.sliceAsBytes(bloom));
|
||||||
|
|
||||||
// Fill in the hash bucket indices
|
// Fill in the hash bucket indices
|
||||||
const buckets = try gpa.alloc(u32, hash.num_buckets);
|
const buckets = try gpa.alloc(u32, hash.num_buckets);
|
||||||
|
|
@ -1284,7 +1281,7 @@ pub const GnuHashSection = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try cwriter.writeAll(mem.sliceAsBytes(buckets));
|
try writer.writeAll(mem.sliceAsBytes(buckets));
|
||||||
|
|
||||||
// Finally, write the hash table
|
// Finally, write the hash table
|
||||||
const table = try gpa.alloc(u32, hash.num_exports);
|
const table = try gpa.alloc(u32, hash.num_exports);
|
||||||
|
|
@ -1300,9 +1297,7 @@ pub const GnuHashSection = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try cwriter.writeAll(mem.sliceAsBytes(table));
|
try writer.writeAll(mem.sliceAsBytes(table));
|
||||||
|
|
||||||
assert(counting.bytes_written == hash.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hasher(name: [:0]const u8) u32 {
|
pub fn hasher(name: [:0]const u8) u32 {
|
||||||
|
|
|
||||||
|
|
@ -186,17 +186,18 @@ const FinalizeNodeResult = struct {
|
||||||
|
|
||||||
/// Updates offset of this node in the output byte stream.
|
/// Updates offset of this node in the output byte stream.
|
||||||
fn finalizeNode(self: *Trie, node_index: Node.Index, offset_in_trie: u32) !FinalizeNodeResult {
|
fn finalizeNode(self: *Trie, node_index: Node.Index, offset_in_trie: u32) !FinalizeNodeResult {
|
||||||
var stream = std.io.countingWriter(std.io.null_writer);
|
var trash_buffer: [64]u8 = undefined;
|
||||||
const writer = stream.writer();
|
var stream: std.Io.Writer.Discarding = .init(&trash_buffer);
|
||||||
|
const writer = &stream.writer;
|
||||||
const slice = self.nodes.slice();
|
const slice = self.nodes.slice();
|
||||||
|
|
||||||
var node_size: u32 = 0;
|
var node_size: u32 = 0;
|
||||||
if (slice.items(.is_terminal)[node_index]) {
|
if (slice.items(.is_terminal)[node_index]) {
|
||||||
const export_flags = slice.items(.export_flags)[node_index];
|
const export_flags = slice.items(.export_flags)[node_index];
|
||||||
const vmaddr_offset = slice.items(.vmaddr_offset)[node_index];
|
const vmaddr_offset = slice.items(.vmaddr_offset)[node_index];
|
||||||
try leb.writeUleb128(writer, export_flags);
|
try writer.writeUleb128(export_flags);
|
||||||
try leb.writeUleb128(writer, vmaddr_offset);
|
try writer.writeUleb128(vmaddr_offset);
|
||||||
try leb.writeUleb128(writer, stream.bytes_written);
|
try writer.writeUleb128(stream.fullCount());
|
||||||
} else {
|
} else {
|
||||||
node_size += 1; // 0x0 for non-terminal nodes
|
node_size += 1; // 0x0 for non-terminal nodes
|
||||||
}
|
}
|
||||||
|
|
@ -206,13 +207,13 @@ fn finalizeNode(self: *Trie, node_index: Node.Index, offset_in_trie: u32) !Final
|
||||||
const edge = &self.edges.items[edge_index];
|
const edge = &self.edges.items[edge_index];
|
||||||
const next_node_offset = slice.items(.trie_offset)[edge.node];
|
const next_node_offset = slice.items(.trie_offset)[edge.node];
|
||||||
node_size += @intCast(edge.label.len + 1);
|
node_size += @intCast(edge.label.len + 1);
|
||||||
try leb.writeUleb128(writer, next_node_offset);
|
try writer.writeUleb128(next_node_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
const trie_offset = slice.items(.trie_offset)[node_index];
|
const trie_offset = slice.items(.trie_offset)[node_index];
|
||||||
const updated = offset_in_trie != trie_offset;
|
const updated = offset_in_trie != trie_offset;
|
||||||
slice.items(.trie_offset)[node_index] = offset_in_trie;
|
slice.items(.trie_offset)[node_index] = offset_in_trie;
|
||||||
node_size += @intCast(stream.bytes_written);
|
node_size += @intCast(stream.fullCount());
|
||||||
|
|
||||||
return .{ .node_size = node_size, .updated = updated };
|
return .{ .node_size = node_size, .updated = updated };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue