mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-25 12:00:31 +00:00
Add x86_64-linux-gnu emulator
I wanted a tiny scriptable meltdown proof way to run userspace programs and visualize how program execution impacts memory. It helps to explain how things like Actually Portable Executable works. It can show you how the GCC generated code is going about manipulating matrices and more. I didn't feel fully comfortable with Qemu and Bochs because I'm not smart enough to understand them. I wanted something like gVisor but with much stronger levels of assurances. I wanted a single binary that'll run, on all major operating systems with an embedded GPL barrier ZIP filesystem that is tiny enough to transpile to JavaScript and run in browsers too. https://justine.storage.googleapis.com/emulator625.mp4
This commit is contained in:
parent
467504308a
commit
f4f4caab0e
1052 changed files with 65667 additions and 7825 deletions
55
tool/build/emubin/emubin.mk
Normal file
55
tool/build/emubin/emubin.mk
Normal file
|
@ -0,0 +1,55 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += TOOL_BUILD_EMUBIN
|
||||
|
||||
TOOL_BUILD_EMUBIN_BINS = \
|
||||
o/$(MODE)/tool/build/emubin/sha256.bin \
|
||||
o/$(MODE)/tool/build/emubin/sha256.bin.dbg \
|
||||
o/$(MODE)/tool/build/emubin/mips.bin \
|
||||
o/$(MODE)/tool/build/emubin/mips.bin.dbg \
|
||||
o/$(MODE)/tool/build/emubin/prime.bin \
|
||||
o/$(MODE)/tool/build/emubin/prime.bin.dbg \
|
||||
o/$(MODE)/tool/build/emubin/pi.bin \
|
||||
o/$(MODE)/tool/build/emubin/pi.bin.dbg
|
||||
|
||||
TOOL_BUILD_EMUBIN_A = o/$(MODE)/tool/build/emubin/emubin.a
|
||||
TOOL_BUILD_EMUBIN_FILES := $(wildcard tool/build/emubin/*)
|
||||
TOOL_BUILD_EMUBIN_SRCS = $(filter %.c,$(TOOL_BUILD_EMUBIN_FILES))
|
||||
TOOL_BUILD_EMUBIN_HDRS = $(filter %.h,$(TOOL_BUILD_EMUBIN_FILES))
|
||||
|
||||
TOOL_BUILD_EMUBIN_OBJS = \
|
||||
$(TOOL_BUILD_EMUBIN_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(TOOL_BUILD_EMUBIN_SRCS:%.c=o/$(MODE)/%.o)
|
||||
|
||||
TOOL_BUILD_EMUBIN_CHECKS = \
|
||||
$(TOOL_BUILD_EMUBIN_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
TOOL_BUILD_EMUBIN_DIRECTDEPS = \
|
||||
LIBC_STUBS \
|
||||
LIBC_TINYMATH
|
||||
|
||||
TOOL_BUILD_EMUBIN_DEPS := \
|
||||
$(call uniq,$(foreach x,$(TOOL_BUILD_EMUBIN_DIRECTDEPS),$($(x))))
|
||||
|
||||
$(TOOL_BUILD_EMUBIN_A): \
|
||||
tool/build/emubin/ \
|
||||
$(TOOL_BUILD_EMUBIN_A).pkg \
|
||||
$(TOOL_BUILD_EMUBIN_OBJS)
|
||||
|
||||
$(TOOL_BUILD_EMUBIN_A).pkg: \
|
||||
$(TOOL_BUILD_EMUBIN_OBJS) \
|
||||
$(foreach x,$(TOOL_BUILD_EMUBIN_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/tool/build/emubin/%.bin.dbg: \
|
||||
$(TOOL_BUILD_EMUCRT) \
|
||||
$(TOOL_BUILD_EMUBIN_DEPS) \
|
||||
$(TOOL_BUILD_EMUBIN_A) \
|
||||
o/$(MODE)/tool/build/emubin/%.o \
|
||||
$(TOOL_BUILD_EMUBIN_A).pkg
|
||||
@$(ELFLINK) -e emucrt -z max-page-size=0x10
|
||||
|
||||
.PHONY: o/$(MODE)/tool/build/emubin
|
||||
o/$(MODE)/tool/build/emubin: \
|
||||
$(TOOL_BUILD_EMUBIN_BINS) \
|
||||
$(TOOL_BUILD_EMUBIN_CHECKS)
|
156
tool/build/emubin/metalsha256.c
Normal file
156
tool/build/emubin/metalsha256.c
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/xmmintrin.h"
|
||||
#include "libc/intrin/repstosb.h"
|
||||
#include "tool/build/emubin/metalsha256.h"
|
||||
|
||||
#define ROTR(a, b) (((a) >> (b)) | ((a) << (32 - (b))))
|
||||
#define CH(x, y, z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define MAJ(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
#define EP0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
|
||||
#define EP1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
|
||||
#define SIG0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ ((x) >> 3))
|
||||
#define SIG1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ ((x) >> 10))
|
||||
|
||||
const uint32_t kMetalSha256Tab[64] = {
|
||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
|
||||
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
||||
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
|
||||
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
|
||||
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
||||
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
||||
};
|
||||
|
||||
void MetalSha256Cleanup(struct MetalSha256Ctx *ctx) {
|
||||
repstosb(ctx, 0, sizeof(*ctx));
|
||||
asm("pxor\t%xmm0,%xmm0\n\t"
|
||||
"pxor\t%xmm1,%xmm1\n\t"
|
||||
"pxor\t%xmm2,%xmm2\n\t"
|
||||
"pxor\t%xmm3,%xmm3\n\t"
|
||||
"pxor\t%xmm4,%xmm4\n\t"
|
||||
"pxor\t%xmm5,%xmm5\n\t"
|
||||
"pxor\t%xmm6,%xmm6\n\t"
|
||||
"pxor\t%xmm7,%xmm7");
|
||||
}
|
||||
|
||||
void MetalSha256Transform(uint32_t state[8], const uint8_t data[64]) {
|
||||
unsigned i;
|
||||
uint32_t a, b, c, d, e, f, g, h, t1, t2, m[64];
|
||||
for (i = 0; i < 16; ++i, data += 4) {
|
||||
m[i] = (uint32_t)data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
}
|
||||
for (; i < 64; ++i) {
|
||||
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
|
||||
}
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
f = state[5];
|
||||
g = state[6];
|
||||
h = state[7];
|
||||
for (i = 0; i < 64; ++i) {
|
||||
t1 = h + EP1(e) + CH(e, f, g) + kMetalSha256Tab[i] + m[i];
|
||||
t2 = EP0(a) + MAJ(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + t1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = t1 + t2;
|
||||
}
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
state[5] += f;
|
||||
state[6] += g;
|
||||
state[7] += h;
|
||||
}
|
||||
|
||||
void MetalSha256Init(struct MetalSha256Ctx *ctx) {
|
||||
ctx->datalen = 0;
|
||||
ctx->bitlen = 0;
|
||||
ctx->state[0] = 0x6a09e667;
|
||||
ctx->state[1] = 0xbb67ae85;
|
||||
ctx->state[2] = 0x3c6ef372;
|
||||
ctx->state[3] = 0xa54ff53a;
|
||||
ctx->state[4] = 0x510e527f;
|
||||
ctx->state[5] = 0x9b05688c;
|
||||
ctx->state[6] = 0x1f83d9ab;
|
||||
ctx->state[7] = 0x5be0cd19;
|
||||
}
|
||||
|
||||
void MetalSha256Update(struct MetalSha256Ctx *ctx, const uint8_t *data,
|
||||
long size) {
|
||||
long i;
|
||||
for (i = 0; i < size; ++i) {
|
||||
ctx->data[ctx->datalen] = data[i];
|
||||
ctx->datalen++;
|
||||
if (ctx->datalen == 64) {
|
||||
MetalSha256Transform(ctx->state, ctx->data);
|
||||
ctx->bitlen += 512;
|
||||
ctx->datalen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MetalSha256Final(struct MetalSha256Ctx *ctx, uint8_t *hash) {
|
||||
long i;
|
||||
i = ctx->datalen;
|
||||
ctx->data[i++] = 0x80;
|
||||
if (ctx->datalen < 56) {
|
||||
repstosb(ctx->data + i, 0, 56 - i);
|
||||
} else {
|
||||
repstosb(ctx->data + i, 0, 64 - i);
|
||||
MetalSha256Transform(ctx->state, ctx->data);
|
||||
repstosb(ctx->data, 0, 56);
|
||||
}
|
||||
ctx->bitlen += ctx->datalen * 8;
|
||||
ctx->data[63] = ctx->bitlen;
|
||||
ctx->data[62] = ctx->bitlen >> 8;
|
||||
ctx->data[61] = ctx->bitlen >> 16;
|
||||
ctx->data[60] = ctx->bitlen >> 24;
|
||||
ctx->data[59] = ctx->bitlen >> 32;
|
||||
ctx->data[58] = ctx->bitlen >> 40;
|
||||
ctx->data[57] = ctx->bitlen >> 48;
|
||||
ctx->data[56] = ctx->bitlen >> 56;
|
||||
MetalSha256Transform(ctx->state, ctx->data);
|
||||
for (i = 0; i < 4; ++i) {
|
||||
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0xff;
|
||||
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0xff;
|
||||
}
|
||||
MetalSha256Cleanup(ctx);
|
||||
}
|
19
tool/build/emubin/metalsha256.h
Normal file
19
tool/build/emubin/metalsha256.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef COSMOPOLITAN_TOOL_BUILD_EMUBIN_METALSHA256_H_
|
||||
#define COSMOPOLITAN_TOOL_BUILD_EMUBIN_METALSHA256_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct MetalSha256Ctx {
|
||||
uint8_t data[64];
|
||||
uint32_t datalen;
|
||||
uint64_t bitlen;
|
||||
uint32_t state[8];
|
||||
};
|
||||
|
||||
void MetalSha256Init(struct MetalSha256Ctx *);
|
||||
void MetalSha256Update(struct MetalSha256Ctx *, const uint8_t *, long);
|
||||
void MetalSha256Final(struct MetalSha256Ctx *, uint8_t *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_TOOL_BUILD_EMUBIN_METALSHA256_H_ */
|
50
tool/build/emubin/mips.c
Normal file
50
tool/build/emubin/mips.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "tool/build/emubin/metalsha256.h"
|
||||
|
||||
#define DISINGENUOUS /* 100 million NOPs is still 100 MIPS lool */
|
||||
|
||||
static void Print(uint8_t c) {
|
||||
asm volatile("out\t%0,$0xE9" : /* no outputs */ : "a"(c) : "memory");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
#ifdef DISINGENUOUS
|
||||
for (i = 0; i < 1400 * 1000 * 1000 / 3; ++i) asm("nop");
|
||||
#else
|
||||
size_t size;
|
||||
struct MetalSha256Ctx ctx;
|
||||
unsigned char hash[32], *data;
|
||||
data = (void *)0x7fffffff0000;
|
||||
size = 0x10000;
|
||||
MetalSha256Init(&ctx);
|
||||
for (i = 0; i < 10; ++i) {
|
||||
MetalSha256Update(&ctx, data, size);
|
||||
}
|
||||
MetalSha256Final(&ctx, hash);
|
||||
for (i = 0; i < sizeof(hash); ++i) {
|
||||
Print("0123456789abcdef"[(hash[i] >> 4) & 15]);
|
||||
Print("0123456789abcdef"[(hash[i] >> 0) & 15]);
|
||||
}
|
||||
Print('\n');
|
||||
#endif
|
||||
return 0;
|
||||
}
|
56
tool/build/emubin/pi.c
Normal file
56
tool/build/emubin/pi.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
|
||||
#if 1
|
||||
#define FLOAT long double
|
||||
#define SQRT sqrtl
|
||||
#else
|
||||
#define FLOAT float
|
||||
#define SQRT sqrt
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Computes π w/ François Viète method.
|
||||
*
|
||||
* make -j8 MODE=tiny
|
||||
* o/tiny/tool/build/emulator.com.dbg -t o/tiny/tool/build/pi.bin
|
||||
*
|
||||
*/
|
||||
FLOAT Main(void) {
|
||||
long i, n;
|
||||
FLOAT pi, q, t;
|
||||
n = VEIL("r", 10);
|
||||
q = 0;
|
||||
t = 1;
|
||||
for (i = 0; i < n; ++i) {
|
||||
q += 2;
|
||||
q = SQRT(q);
|
||||
t *= q / 2;
|
||||
}
|
||||
return 2 / t;
|
||||
}
|
||||
|
||||
volatile FLOAT st0;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
st0 = Main();
|
||||
return 0;
|
||||
}
|
42
tool/build/emubin/prime.c
Normal file
42
tool/build/emubin/prime.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
|
||||
noinline bool IsPrime(int i) {
|
||||
int j, n;
|
||||
for (j = 3, n = VEIL("r", 3); j <= n; j += 2) {
|
||||
if (VEIL("r", i) % VEIL("r", j) == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Places 10th prime number in RAX.
|
||||
*/
|
||||
int main(int argc, char *argv[]) {
|
||||
int i, c;
|
||||
for (c = i = 0; c < VEIL("r", 10); ++i) {
|
||||
if (IsPrime(i)) {
|
||||
++c;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
53
tool/build/emubin/sha256.c
Normal file
53
tool/build/emubin/sha256.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "tool/build/emubin/metalsha256.h"
|
||||
|
||||
#define SHA256_BLOCK_SIZE 32
|
||||
|
||||
#define OUTB(PORT, BYTE) asm volatile("outb\t%b1,%0" : : "N"(PORT), "a"(BYTE))
|
||||
#define INW(PORT) \
|
||||
({ \
|
||||
int Word; \
|
||||
asm volatile("in\t%1,%0" : "=a"(Word) : "N"(PORT)); \
|
||||
Word; \
|
||||
})
|
||||
|
||||
static void PrintHexBytes(int n, const uint8_t p[n]) {
|
||||
int i;
|
||||
for (i = 0; i < n; ++i) {
|
||||
OUTB(0xE9, "0123456789abcdef"[(p[i] >> 4) & 15]);
|
||||
OUTB(0xE9, "0123456789abcdef"[(p[i] >> 0) & 15]);
|
||||
}
|
||||
OUTB(0xE9, '\n');
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int rc;
|
||||
uint8_t hash[32], buf[1];
|
||||
struct MetalSha256Ctx ctx;
|
||||
MetalSha256Init(&ctx);
|
||||
while ((rc = INW(0xE9)) != -1) {
|
||||
buf[0] = rc;
|
||||
MetalSha256Update(&ctx, buf, sizeof(buf));
|
||||
}
|
||||
MetalSha256Final(&ctx, hash);
|
||||
PrintHexBytes(sizeof(hash), hash);
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue