lib/tldr/src/formats/elf/icf/hash.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 Symbol = elf.format.Symbol;
8 const hashU64 = elf.format.hashU64;
9 const sectionBytes = elf.format.sectionBytes;
10
11 pub fn section(object: ObjectFile, section_index: usize) model.Error!u64 {
12 const input_section = object.sections[section_index];
13 var value: u64 = 0x9ae16a3b2f90404f;
14 value = hashU64(value, input_section.section_type);
15 value = hashU64(value, input_section.flags);
16 value = hashU64(value, @max(input_section.alignment, 1));
17 value = hashU64(value, input_section.size);
18 value = std.hash.Wyhash.hash(value, try sectionBytes(object.bytes, input_section));
19 for (object.relocationsForSection(section_index)) |entry| {
20 if (elf.relocation.isNone(entry)) continue;
21 value = hashU64(value, entry.offset);
22 value = hashU64(value, entry.relocationType());
23 value = hashU64(value, @as(u64, @bitCast(entry.addend)));
24 if (entry.symbolIndex() >= object.symbols.len) return error.UndefinedSymbol;
25 value = relocationTarget(value, object.symbols[@intCast(entry.symbolIndex())]);
26 }
27 return value;
28 }
29
30 fn relocationTarget(seed: u64, symbol: Symbol) u64 {
31 var value = seed;
32 value = hashU64(value, symbol.binding());
33 value = hashU64(value, symbol.kind());
34 value = hashU64(value, symbol.section_index);
35 return std.hash.Wyhash.hash(value, symbol.name);
36 }