lib/tldr/src/formats/elf/image/zero.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const root = @import("../../../root.zig");
3 const elf = @import("../root.zig");
4
5 const model = root.model;
6 const ObjectFile = elf.parser.ObjectFile;
7 const ObjectLayout = elf.layout.ObjectLayout;
8 const OutputSection = elf.layout.OutputSection;
9 const output_section_count = elf.output_section.output_section_count;
10 const contributionAt = elf.layout.contributionAt;
11
12 pub fn unwrittenFileRanges(
13 image: []u8,
14 objects: []const ObjectFile,
15 layouts: []const ObjectLayout,
16 output_sections: []const OutputSection,
17 metadata_start: u64,
18 metadata_end: u64,
19 section_header_offset: u64,
20 ) model.Error!void {
21 var section_cursors = @as([output_section_count]u64, @splat(0));
22 var file_cursor: u64 = 0;
23 for (output_sections, 0..) |section, output_index| {
24 if (section.logicalSize() == 0) continue;
25 try range(image, file_cursor, section.file_offset);
26 if (section.kind.isNoBits()) {
27 file_cursor = section.file_offset;
28 continue;
29 }
30
31 const section_end = section.file_offset + section.fileLoadSize();
32 section_cursors[output_index] = section.file_offset;
33 file_cursor = section_end;
34 }
35
36 try contributionGaps(image, objects, layouts, output_sections, §ion_cursors);
37
38 for (output_sections, 0..) |section, output_index| {
39 if (section.logicalSize() == 0) continue;
40 if (section.kind.isNoBits()) continue;
41 try range(image, section_cursors[output_index], section.file_offset + section.fileLoadSize());
42 }
43
44 try range(image, file_cursor, metadata_start);
45 try range(image, metadata_end, section_header_offset);
46 }
47
48 fn contributionGaps(
49 image: []u8,
50 objects: []const ObjectFile,
51 layouts: []const ObjectLayout,
52 output_sections: []const OutputSection,
53 section_cursors: *[output_section_count]u64,
54 ) model.Error!void {
55 for (objects, 0..) |object, object_index| {
56 const object_layout = layouts[object_index];
57 for (object.sections, 0..) |section, section_index| {
58 if (section.section_type == std.elf.SHT_NOBITS) continue;
59 const contribution = contributionAt(object_layout.sections, section_index) orelse continue;
60 const output_index = contribution.outputIndex();
61 const output = output_sections[output_index];
62
63 const payload_start = output.file_offset + contribution.offset;
64 const payload_end = payload_start + contribution.size;
65 const reserve_end = output.file_offset + contribution.offset + contribution.reserved_size;
66 try range(image, section_cursors[output_index], payload_start);
67 try range(image, payload_end, reserve_end);
68 section_cursors[output_index] = reserve_end;
69 }
70 }
71 }
72
73 pub fn range(image: []u8, start: u64, end: u64) model.Error!void {
74 if (end < start) return error.InvalidRange;
75 if (start == end) return;
76 const image_len: u64 = @intCast(image.len);
77 if (end > image_len) return error.InvalidRange;
78 const first: usize = @intCast(start);
79 const last: usize = @intCast(end);
80 @memset(image[first..last], 0);
81 }