tiny.profiling.code_layout
Defined in tiny.profiling.
API (5)
Actions
Public operations.
Types and contracts
Public types and contracts.
Source
Source: src/profiling/layout.zig
zig
const std = @import("std");const capture = @import("capture");const pretty = @import("pretty");const pretty_usage = @import("pretty_usage");const sys = @import("sys");const pretty_json = pretty.json;const max_image_bytes = 512 * 1024 * 1024;pub const Image = struct { path: []const u8, fingerprint: capture.code_layout.Fingerprint,};pub const Report = struct { images: []const Image, distinct_code_digests: usize, pub fn variationObserved(self: Report) bool { return self.distinct_code_digests > 1; }};const Options = struct { paths: []const []const u8, json: bool,};pub fn run(allocator: std.mem.Allocator, args: []const []const u8) !u8 { const options = try parseArgs(allocator, args); const report = try inspect(allocator, options.paths); if (options.json) { try writeJson(report); } else { try writeText(allocator, report); } return 0;}pub fn inspect(allocator: std.mem.Allocator, paths: []const []const u8) !Report { var images: std.ArrayList(Image) = .empty; for (paths) |path| { const fingerprint = fingerprint: { const bytes = try sys.fs.readFileAlloc(allocator, path, max_image_bytes); defer allocator.free(bytes); break :fingerprint try capture.code_layout.fingerprintElf(allocator, bytes); }; try images.append(allocator, .{ .path = path, .fingerprint = fingerprint, }); } const owned = try images.toOwnedSlice(allocator); return .{ .images = owned, .distinct_code_digests = distinctDigestCount(owned), };}fn parseArgs(allocator: std.mem.Allocator, args: []const []const u8) !Options { var paths: std.ArrayList([]const u8) = .empty; var json = false; for (args) |arg| { if (std.mem.eql(u8, arg, "--json")) { json = true; } else if (std.mem.startsWith(u8, arg, "-")) { return error.UnknownArgument; } else { try paths.append(allocator, arg); } } if (paths.items.len == 0) return error.MissingImagePath; return .{ .paths = try paths.toOwnedSlice(allocator), .json = json };}fn distinctDigestCount(images: []const Image) usize { var distinct: usize = 0; for (images, 0..) |image, index| { var seen = false; for (images[0..index]) |prior| { if (std.mem.eql(u8, &image.fingerprint.digest, &prior.fingerprint.digest)) { seen = true; break; } } if (!seen) distinct += 1; } return distinct;}fn writeText(allocator: std.mem.Allocator, report: Report) !void { const terminal = pretty_usage.Terminal.stdout(allocator, .{}); try terminal.writeTextFmt("code layout: {d} image(s), {d} distinct code digest(s), variation {s}\n", .{ report.images.len, report.distinct_code_digests, if (report.variationObserved()) "observed" else "not observed", }); for (report.images) |image| { const hex = image.fingerprint.hex(); try terminal.writeTextFmt(" {s} {s} {d} section(s), {d} byte(s), 0x{x}-0x{x}\n", .{ hex, image.path, image.fingerprint.executable_sections, image.fingerprint.executable_bytes, image.fingerprint.first_address, image.fingerprint.last_address_end, }); }}fn writeJson(report: Report) !void { var buffer: [8192]u8 = undefined; var file_writer = sys.stdio.stdout().writer(std.Options.debug_io, &buffer); defer file_writer.interface.flush() catch {}; var out = pretty_json.Writer.init(&file_writer.interface, .minified); try out.beginObject(); try out.objectField("schema"); try out.write(capture.code_layout.schema); try out.objectField("input_count"); try out.write(report.images.len); try out.objectField("distinct_code_digests"); try out.write(report.distinct_code_digests); try out.objectField("code_variation_observed"); try out.write(report.variationObserved()); try out.objectField("images"); try out.beginArray(); for (report.images) |image| { const hex = image.fingerprint.hex(); try out.beginObject(); try out.objectField("path"); try out.write(image.path); try out.objectField("format"); try out.write("elf"); try out.objectField("code_digest_sha256"); try out.write(&hex); try out.objectField("executable_sections"); try out.write(image.fingerprint.executable_sections); try out.objectField("executable_bytes"); try out.write(image.fingerprint.executable_bytes); try out.objectField("first_address"); try out.write(image.fingerprint.first_address); try out.objectField("last_address_end"); try out.write(image.fingerprint.last_address_end); try out.endObject(); } try out.endArray(); try out.endObject(); try file_writer.interface.writeByte('\n');}test "code layout CLI parses image paths" { var arena_state = std.heap.ArenaAllocator.init(std.testing.allocator); defer arena_state.deinit(); const options = try parseArgs(arena_state.allocator(), &.{ "first", "--json", "second" }); try std.testing.expect(options.json); try std.testing.expectEqual(@as(usize, 2), options.paths.len); try std.testing.expectEqualStrings("first", options.paths[0]); try std.testing.expectEqualStrings("second", options.paths[1]); try std.testing.expectError(error.MissingImagePath, parseArgs(arena_state.allocator(), &.{"--json"}));}Source: src/profiling/root.zig:19
zig
pub const code_layout = @import("layout.zig");Audit
| Definitions | 6 |
|---|---|
| Public names | 6 |
| Members | 4 |
| Version | 26.7.0 |
| Revision | daab053ee433 |