lib/tldr/src/formats/elf/layout/output.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const root = @import("../../../root.zig");
 2 const elf = @import("../root.zig");
 3 
 4 const model = root.model;
 5 const OutputSection = elf.layout.OutputSection;
 6 const output_section_count = elf.output_section.output_section_count;
 7 const ehdr_size = elf.format.ehdr_size;
 8 const phdr_size = elf.format.phdr_size;
 9 const alignForward = elf.format.alignForward;
10 const alignForwardU64 = elf.format.alignForwardU64;
11 const reserveSize = elf.layout.reserveSize;
12 
13 pub fn countLive(output_sections: []const OutputSection) usize {
14     var count: usize = 0;
15     for (output_sections) |section| {
16         if (section.logicalSize() != 0) count += 1;
17     }
18     return count;
19 }
20 
21 pub fn assign(
22     output_sections: *[output_section_count]OutputSection,
23     options: model.LinkOptions,
24     program_header_count: usize,
25 ) model.Error!void {
26     var file_offset = ehdr_size + program_header_count * phdr_size;
27     var address_cursor = options.image_base;
28     var section_index: u16 = 1;
29     var previous_alloc_was_tls = false;
30     for (output_sections) |*section| {
31         const logical_size = section.logicalSize();
32         if (logical_size == 0) continue;
33         file_offset = alignForward(file_offset, @intCast(@max(section.alignment, 1)));
34         section.file_offset = @intCast(file_offset);
35         section.address = if (section.kind.isAllocated())
36             if (section.kind.isTls() and previous_alloc_was_tls)
37                 address_cursor
38             else
39                 loadAddressForFileOffset(address_cursor, section.file_offset, options.page_size)
40         else
41             0;
42         section.reserved_size = reserveSize(logical_size, section.alignment, options);
43         section.section_index = section_index;
44         section_index += 1;
45         if (section.kind.isAllocated()) {
46             address_cursor = section.address + section.reserved_size;
47             previous_alloc_was_tls = section.kind.isTls();
48         }
49         file_offset += @intCast(section.fileLoadSize());
50     }
51 }
52 
53 fn loadAddressForFileOffset(address_cursor: u64, file_offset: u64, page_size: u64) u64 {
54     if (page_size <= 1) return address_cursor + file_offset;
55     return alignForwardU64(address_cursor, page_size) + file_offset % page_size;
56 }