| ... | @@ -3290,13 +3290,11 @@ pub const gnu_hash = struct { | ... | @@ -3290,13 +3290,11 @@ pub const gnu_hash = struct { |
| 3290 | | 3290 | |
| 3291 | /// Calculate the hash value for a name | 3291 | /// Calculate the hash value for a name |
| 3292 | pub fn calculate(name: []const u8) u32 { | 3292 | pub fn calculate(name: []const u8) u32 { |
| 3293 | var hash: u32 = 5381; | 3293 | var h: u32 = 5381; |
| 3294 | | | |
| 3295 | for (name) |char| { | 3294 | for (name) |char| { |
| 3296 | hash = (hash << 5) +% hash +% char; | 3295 | h = (h << 5) +% h +% char; |
| 3297 | } | 3296 | } |
| 3298 | | 3297 | return h; |
| 3299 | return hash; | | |
| 3300 | } | 3298 | } |
| 3301 | | 3299 | |
| 3302 | test calculate { | 3300 | test calculate { |
| ... | @@ -3308,6 +3306,39 @@ pub const gnu_hash = struct { | ... | @@ -3308,6 +3306,39 @@ pub const gnu_hash = struct { |
| 3308 | } | 3306 | } |
| 3309 | }; | 3307 | }; |
| 3310 | | 3308 | |
| | 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 |
| | 3314 | pub 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 | |
| 3311 | pub const EhdrFlags = packed union(Word) { | 3342 | pub const EhdrFlags = packed union(Word) { |
| 3312 | int: u32, | 3343 | int: u32, |
| 3313 | loongarch: Loongarch, | 3344 | loongarch: Loongarch, |