| ... | ... | @@ -10,6 +10,7 @@ const fs = std.fs; |
| 10 | 10 | const elf = std.elf; |
| 11 | 11 | const log = std.log.scoped(.link); |
| 12 | 12 | |
| 13 | const Atom = @import("Elf/Atom.zig"); |
| 13 | 14 | const Module = @import("../Module.zig"); |
| 14 | 15 | const Compilation = @import("../Compilation.zig"); |
| 15 | 16 | const Dwarf = @import("Dwarf.zig"); |
| ... | ... | @@ -31,6 +32,8 @@ const Air = @import("../Air.zig"); |
| 31 | 32 | const Liveness = @import("../Liveness.zig"); |
| 32 | 33 | const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 33 | 34 | |
| 35 | pub const TextBlock = Atom; |
| 36 | |
| 34 | 37 | const default_entry_addr = 0x8000000; |
| 35 | 38 | |
| 36 | 39 | pub const base_tag: File.Tag = .elf; |
| ... | ... | @@ -188,62 +191,10 @@ const ideal_factor = 3; |
| 188 | 191 | /// it as a possible place to put new symbols, it must have enough room for this many bytes |
| 189 | 192 | /// (plus extra for reserved capacity). |
| 190 | 193 | const minimum_text_block_size = 64; |
| 191 | | const min_text_capacity = padToIdeal(minimum_text_block_size); |
| 194 | pub const min_text_capacity = padToIdeal(minimum_text_block_size); |
| 192 | 195 | |
| 193 | 196 | pub const PtrWidth = enum { p32, p64 }; |
| 194 | 197 | |
| 195 | | pub const TextBlock = struct { |
| 196 | | /// Each decl always gets a local symbol with the fully qualified name. |
| 197 | | /// The vaddr and size are found here directly. |
| 198 | | /// The file offset is found by computing the vaddr offset from the section vaddr |
| 199 | | /// the symbol references, and adding that to the file offset of the section. |
| 200 | | /// If this field is 0, it means the codegen size = 0 and there is no symbol or |
| 201 | | /// offset table entry. |
| 202 | | local_sym_index: u32, |
| 203 | | /// This field is undefined for symbols with size = 0. |
| 204 | | offset_table_index: u32, |
| 205 | | /// Points to the previous and next neighbors, based on the `text_offset`. |
| 206 | | /// This can be used to find, for example, the capacity of this `TextBlock`. |
| 207 | | prev: ?*TextBlock, |
| 208 | | next: ?*TextBlock, |
| 209 | | |
| 210 | | dbg_info_atom: Dwarf.Atom, |
| 211 | | |
| 212 | | pub const empty = TextBlock{ |
| 213 | | .local_sym_index = 0, |
| 214 | | .offset_table_index = undefined, |
| 215 | | .prev = null, |
| 216 | | .next = null, |
| 217 | | .dbg_info_atom = undefined, |
| 218 | | }; |
| 219 | | |
| 220 | | /// Returns how much room there is to grow in virtual address space. |
| 221 | | /// File offset relocation happens transparently, so it is not included in |
| 222 | | /// this calculation. |
| 223 | | fn capacity(self: TextBlock, elf_file: Elf) u64 { |
| 224 | | const self_sym = elf_file.local_symbols.items[self.local_sym_index]; |
| 225 | | if (self.next) |next| { |
| 226 | | const next_sym = elf_file.local_symbols.items[next.local_sym_index]; |
| 227 | | return next_sym.st_value - self_sym.st_value; |
| 228 | | } else { |
| 229 | | // We are the last block. The capacity is limited only by virtual address space. |
| 230 | | return std.math.maxInt(u32) - self_sym.st_value; |
| 231 | | } |
| 232 | | } |
| 233 | | |
| 234 | | fn freeListEligible(self: TextBlock, elf_file: Elf) bool { |
| 235 | | // No need to keep a free list node for the last block. |
| 236 | | const next = self.next orelse return false; |
| 237 | | const self_sym = elf_file.local_symbols.items[self.local_sym_index]; |
| 238 | | const next_sym = elf_file.local_symbols.items[next.local_sym_index]; |
| 239 | | const cap = next_sym.st_value - self_sym.st_value; |
| 240 | | const ideal_cap = padToIdeal(self_sym.st_size); |
| 241 | | if (cap <= ideal_cap) return false; |
| 242 | | const surplus = cap - ideal_cap; |
| 243 | | return surplus >= min_text_capacity; |
| 244 | | } |
| 245 | | }; |
| 246 | | |
| 247 | 198 | pub const Export = struct { |
| 248 | 199 | sym_index: ?u32 = null, |
| 249 | 200 | }; |
| ... | ... | @@ -3052,7 +3003,7 @@ fn getLDMOption(target: std.Target) ?[]const u8 { |
| 3052 | 3003 | } |
| 3053 | 3004 | } |
| 3054 | 3005 | |
| 3055 | | fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| 3006 | pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| 3056 | 3007 | return actual_size +| (actual_size / ideal_factor); |
| 3057 | 3008 | } |
| 3058 | 3009 | |