Select Git revision
mockup_prelude.cc
mockup_prelude.cc 2.79 KiB
#include "os.h"
#include "test/test.h"
#include "machine.h"
#include <stdio.h>
extern "C" {
extern const uint32_t _sdata_os_canonical, _edata_os_canonical;
extern const uint32_t _sdata_arch_canonical, _edata_arch_canonical;
}
// **********************************************************************
// Murmur3 implementation
//
// See https://en.wikipedia.org/wiki/MurmurHash and
// http://programmers.stackexchange.com/a/145633
//
// Adapted almost literally from:
// https://github.com/aappleby/smhasher/blob/61a0530f28277f2e850bfc39600ce61d02b518de/src/MurmurHash3.cpp
// **********************************************************************
#define ROTL32(x, y) ((x << y) | (x >> (32 - y)))
uint32_t murmur3_32(const char *key, uint32_t len, uint32_t seed) {
const uint8_t *data = (const uint8_t*)key;
const int nblocks = len / 4;
uint32_t h1 = seed;
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
// body
const uint32_t *blocks = (const uint32_t*)(data + nblocks*4);
for (int i = -nblocks; i < 0; i++) {
uint32_t k1 = blocks[i];
k1 *= c1;
k1 = ROTL32(k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = ROTL32(h1, 13);
h1 = h1*5+0xe6546b64;
}
// tail
const uint8_t *tail = (const uint8_t*)(data + nblocks*4);
uint32_t k1 = 0;
switch (len & 3) {
case 3:
k1 ^= tail[2] << 16;
// intentional fallthrough
case 2:
k1 ^= tail[1] << 8;
// intentional fallthrough
case 1:
k1 ^= tail[0];
k1 *= c1;
k1 = ROTL32(k1, 15);
k1 *= c2;
h1 ^= k1;
}
// finalization
h1 ^= len;
h1 ^= h1 >> 16;
h1 *= 0x85ebca6b;
h1 ^= h1 >> 13;
h1 *= 0xc2b2ae35;
h1 ^= h1 >> 16;
return h1;
}
// **********************************************************************
// End Murmur3
// **********************************************************************
uint32_t hash_os_state() {
const char *start = (const char*)&_sdata_os_canonical;
const char *end = (const char*)&_edata_os_canonical;
uint32_t len = end-start;
uint32_t seed = 0; // be deterministic
uint32_t first_hash = murmur3_32(start, len, seed);
start = (const char*)&_sdata_arch_canonical;
end = (const char*)&_edata_arch_canonical;
len = end - start;
uint32_t second_hash = murmur3_32(start, len, seed);
return first_hash ^ second_hash;
}
void _print_os_state(const char *format, const char *syscall, const char *func) {
printf(format, hash_os_state(), syscall, func);
printf("\n");
fflush(stdout);
}
void os_main(void) {
StartOS(0);
}
int _decisionMaker(const char *format, int i) {
printf(format, i);
printf("\n");
fflush(stdout);
int res = (getchar() == '0') ? 0 : 1;
getchar(); // newline
return res;
}