diff options
| author | geemili <opensource@geemili.xyz> | 2025-02-10 18:47:14 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-02-22 17:33:49 -0500 |
| commit | 6ef2384c07ef6817f134ffc61e34bcea6e87df92 (patch) | |
| tree | 44b9690d032aea3d935762bef4b8cc064797f873 /lib/std/elf.zig | |
| parent | b7512c3e5d1734c301b8e5c1cda0385b0a967e0c (diff) | |
| download | zig-6ef2384c07ef6817f134ffc61e34bcea6e87df92.tar.gz zig-6ef2384c07ef6817f134ffc61e34bcea6e87df92.zip | |
std.DynLib: add support for DT_GNU_HASH sections in elf files
Diffstat (limited to 'lib/std/elf.zig')
| -rw-r--r-- | lib/std/elf.zig | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/std/elf.zig b/lib/std/elf.zig index f326b6b5a9..28f7cc2482 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -2395,3 +2395,40 @@ pub const STRNAME = genSpecialMemberName("//"); pub const SYM64NAME = genSpecialMemberName("/SYM64/"); pub const SYMDEFNAME = genSpecialMemberName("__.SYMDEF"); pub const SYMDEFSORTEDNAME = genSpecialMemberName("__.SYMDEF SORTED"); + +pub const gnu_hash = struct { + + // See https://flapenguin.me/elf-dt-gnu-hash + + pub const Header = extern struct { + nbuckets: u32, + symoffset: u32, + bloom_size: u32, + bloom_shift: u32, + }; + + pub const ChainEntry = packed struct(u32) { + end_of_chain: bool, + /// Contains the top bits of the hash value. + hash: u31, + }; + + /// Calculate the hash value for a name + pub fn calculate(name: []const u8) u32 { + var hash: u32 = 5381; + + for (name) |char| { + hash = (hash << 5) +% hash +% char; + } + + return hash; + } + + test calculate { + try std.testing.expectEqual(0x00001505, calculate("")); + try std.testing.expectEqual(0x156b2bb8, calculate("printf")); + try std.testing.expectEqual(0x7c967e3f, calculate("exit")); + try std.testing.expectEqual(0xbac212a0, calculate("syscall")); + try std.testing.expectEqual(0x8ae9f18e, calculate("flapenguin.me")); + } +}; |
