authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-08-12 12:18:15+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-08-16 09:30:30+01:00
logc7a169280d51359f8206e86cf0f6289e902d0c2e
tree45862a38b83cb4a11afa4453669aef17b1504e15
parent44449730c731a50dcdaaef04dff2755418f2546c
signaturelock-open Commit is signed but in an unrecognized format.

std.elf: add definitions for SHT_HASH header and hash function


1 files changed, 36 insertions(+), 5 deletions(-)

lib/std/elf.zig+36-5
......@@ -3290,13 +3290,11 @@ pub const gnu_hash = struct {
32903290
32913291 /// Calculate the hash value for a name
32923292 pub fn calculate(name: []const u8) u32 {
3293 var hash: u32 = 5381;
3294
3293 var h: u32 = 5381;
32953294 for (name) |char| {
3296 hash = (hash << 5) +% hash +% char;
3295 h = (h << 5) +% h +% char;
32973296 }
3298
3299 return hash;
3297 return h;
33003298 }
33013299
33023300 test calculate {
......@@ -3308,6 +3306,39 @@ pub const gnu_hash = struct {
33083306 }
33093307};
33103308
3309/// Things for the `SHT.HASH` section type.
3310///
3311/// Resources:
3312/// * https://refspecs.linuxfoundation.org/elf/gabi4+/ch5.dynamic.html#hash
3313/// * https://flapenguin.me/elf-dt-hash
3314pub const hash = struct {
3315 pub fn calculate(name: []const u8) u32 {
3316 var h: u32 = 0;
3317 for (name) |c| {
3318 h = (h << 4) +% c;
3319 const g = h & 0xF000_0000;
3320 h = (h ^ (g >> 24)) & ~g;
3321 }
3322 return h;
3323 }
3324
3325 /// The header of a `SHT.HASH` section. Immediately followed by:
3326 /// * `buckets: [nbucket]u32`
3327 /// * `chains: [nchain]u32`
3328 ///
3329 /// The bucket for a symbol named `name` is `std.elf.hash.calculate(name) % nbuckets`.
3330 ///
3331 /// `buckets[b]` is the index of the first symbol in bucket `b`. If bucket `b` is empty then the
3332 /// value is 0 (`STN_UNDEF`).
3333 ///
3334 /// `chain[sym_index]` is the index of the next symbol in the same bucket as `sym_index`. If
3335 /// `sym_index` is the last symbol in its bucket then the value is 0 (`STN_UNDEF`).
3336 pub const Header = extern struct {
3337 nbucket: u32,
3338 nchain: u32,
3339 };
3340};
3341
33113342pub const EhdrFlags = packed union(Word) {
33123343 int: u32,
33133344 loongarch: Loongarch,