kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

link_image_id.c (1797B)


      1 /* link_image_id_compute: format-agnostic 16-byte identity hash for a
      2  * resolved LinkImage.
      3  *
      4  * Two FNV-1a 64-bit streams with different seeds produce 128 bits.  The
      5  * mix covers each segment's vaddr, file_size, and post-shift bytes, so
      6  * the digest changes if either content or layout shifts.  Determinism
      7  * (no time / random component) is intentional — reproducible builds.
      8  *
      9  * Wrapped per format:
     10  *   - ELF      .note.gnu.build-id (link_emit_elf)
     11  *   - Mach-O   LC_UUID payload    (link_emit_macho, Phase 3)
     12  *   - COFF/PE  debug directory    (deferred)
     13  *
     14  * Lived in link_elf.c through Phase 0; lifted out so the Mach-O writer
     15  * sees the same bytes. */
     16 
     17 #include "core/core.h"
     18 #include "link/link_internal.h"
     19 
     20 static u64 fnv1a64(const u8* data, size_t n, u64 seed) {
     21   const u64 PRIME = 0x100000001b3ull;
     22   u64 h = seed;
     23   size_t i;
     24   for (i = 0; i < n; ++i) {
     25     h ^= (u64)data[i];
     26     h *= PRIME;
     27   }
     28   return h;
     29 }
     30 
     31 void link_image_id_compute(const LinkImage* img, u8 out[LINK_IMAGE_ID_BYTES]) {
     32   const u64 SEED_LO = 0xcbf29ce484222325ull;
     33   const u64 SEED_HI = 0x14650fb0739d0383ull;
     34   u64 lo = SEED_LO, hi = SEED_HI;
     35   u32 i;
     36   for (i = 0; i < img->nsegments; ++i) {
     37     const LinkSegment* seg = &img->segments[i];
     38     u64 vaddr = seg->vaddr;
     39     u64 fsz = seg->file_size;
     40     lo = fnv1a64((const u8*)&vaddr, sizeof vaddr, lo);
     41     lo = fnv1a64((const u8*)&fsz, sizeof fsz, lo);
     42     hi = fnv1a64((const u8*)&vaddr, sizeof vaddr, hi);
     43     hi = fnv1a64((const u8*)&fsz, sizeof fsz, hi);
     44     if (img->segment_bytes[i] && fsz) {
     45       lo = fnv1a64(img->segment_bytes[i], (size_t)fsz, lo);
     46       hi = fnv1a64(img->segment_bytes[i], (size_t)fsz, hi);
     47     }
     48   }
     49   for (i = 0; i < 8; ++i) out[i] = (u8)(lo >> (i * 8));
     50   for (i = 0; i < 8; ++i) out[8 + i] = (u8)(hi >> (i * 8));
     51 }