Skip to content

Commit 311dac4

Browse files
committed
Initial commit
0 parents  commit 311dac4

12 files changed

+477
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
able
2+
config.mk
3+
*.o
4+
*~

LICENSE

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Copyright (c) 2015 Mark Smith <[email protected]>
2+
Copyright (c) 2015 Ryan Siddle <[email protected]>
3+
Copyright (c) 2015 Merj Ltd
4+
5+
Permission to use, copy, modify, and distribute this software for any purpose
6+
with or without fee is hereby granted, provided that the above copyright notice
7+
and this permission notice appear in all copies.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
11+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
13+
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
14+
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
15+
THIS SOFTWARE.

Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
BIN?=able
2+
SRCS=trap.c libable_shim.c term.c able.c
3+
LIBS=-lpthread -lable
4+
5+
.include "config.mk"
6+
7+
OBJS+=${SRCS:N*.h:R:S/$/.o/}
8+
9+
.PHONY: build clean install uninstall
10+
11+
build: ${BIN}
12+
13+
clean:
14+
-rm -vf ${OBJS} ${BIN}
15+
-rm -vf ${BIN}.core
16+
17+
install: ${BIN}
18+
@mkdir -p ${BINDIR}
19+
install -m 0755 ${BIN} ${BINDIR}/${BIN}
20+
21+
uninstall:
22+
-rm -vf ${BINDIR}/${BIN}
23+
24+
${BIN}: ${OBJS}
25+
${LD} ${LDFLAGS} -o ${BIN} ${OBJS} ${LIBS}

README

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
WELCOME TO ABLE!
2+
3+
able implements an efficient, portable and secure general-purpose virtual
4+
machine and virtual network using libable
5+
6+
GETTING STARTED
7+
8+
BSD Make and Clang are required to build and install able
9+
10+
Building and installing on OpenBSD
11+
12+
$ cp config.mk.def config.mk
13+
$ make install
14+
...
15+
$
16+
17+
Building and installing on Ubuntu
18+
19+
# apt install bmake clang
20+
...
21+
# exit
22+
$ cp config.mk.def config.mk
23+
$ bmake -DCOMPAT_LINUX install
24+
...
25+
$
26+
27+
Building and installing on macOS
28+
29+
# brew install bmake
30+
...
31+
# exit
32+
$ cp config.mk.def config.mk
33+
$ bmake -DCOMPAT_MACOS install
34+
...
35+
$
36+
37+
GETTING INVOLVED
38+
39+
Contact Details
40+
41+
Find us online at ablevm.org or email us at [email protected]
42+
43+
Code of Conduct
44+
45+
Respect each other and please don't spam
46+
47+
LICENSE
48+
49+
ISC-style license

able.c

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#include <stdatomic.h>
2+
#include <pthread.h>
3+
#include <able/able.h>
4+
#include <stdlib.h>
5+
#include <unistd.h>
6+
#include <err.h>
7+
#include <sys/stat.h>
8+
#include <fcntl.h>
9+
#include <sys/mman.h>
10+
#include <string.h>
11+
#include <stdio.h>
12+
#include <signal.h>
13+
#include "trap.h"
14+
#include "libable_shim.h"
15+
#include "term.h"
16+
17+
extern char *__progname;
18+
19+
void
20+
usage() {
21+
fprintf(stderr, "usage: %s [-hv] [-s size] [file]\n", __progname);
22+
exit(1);
23+
}
24+
25+
long
26+
eatoi(const char *s) {
27+
long v;
28+
char *ep;
29+
v = strtol(s, &ep, 10);
30+
switch (ep[0]) {
31+
case 'G':
32+
v *= 1024;
33+
case 'M':
34+
v *= 1024;
35+
case 'K':
36+
case 'B':
37+
v *= 1024;
38+
}
39+
return v;
40+
}
41+
42+
int
43+
main(int argc, char *argv[]) {
44+
int v;
45+
v = 0;
46+
long bc;
47+
bc = 0;
48+
char *ifn;
49+
ifn = NULL;
50+
51+
char c;
52+
while ((c = getopt(argc, argv, "hvs:")) != -1) {
53+
switch (c) {
54+
case 's':
55+
if (bc != 0)
56+
usage();
57+
bc = eatoi(optarg);
58+
break;
59+
case 'v':
60+
v++;
61+
break;
62+
case 'h':
63+
default:
64+
usage();
65+
}
66+
}
67+
68+
argc -= optind;
69+
argv += optind;
70+
71+
switch (argc) {
72+
case 0:
73+
asprintf(&ifn, "%s.img", __progname);
74+
break;
75+
case 1:
76+
ifn = argv[0];
77+
break;
78+
default:
79+
usage();
80+
}
81+
82+
if (bc == 0) {
83+
struct stat ifs;
84+
int rc;
85+
rc = stat(ifn, &ifs);
86+
if (rc == -1)
87+
err(3, "%s", ifn);
88+
bc = ifs.st_size;
89+
}
90+
91+
int ifd;
92+
ifd = open(ifn, O_RDWR);
93+
if (ifd == -1)
94+
err(3, "open");
95+
void *b;
96+
b = mmap(NULL, bc, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0);
97+
if (b == MAP_FAILED)
98+
err(3, "mmap");
99+
close(ifd);
100+
101+
// virtual machine config
102+
103+
// terminal input
104+
term_recv_t i0;
105+
memset(&i0, 0, sizeof(i0));
106+
107+
able_task_t i0t;
108+
memset(&i0t, 0, sizeof(i0t));
109+
i0t.f = (able_task_exec_t)term_recv_exec;
110+
i0t.u = &i0;
111+
112+
able_wire_t i0w[256];
113+
memset(&i0w, 0, sizeof(i0w));
114+
115+
// terminal output
116+
term_send_t o0;
117+
memset(&o0, 0, sizeof(o0));
118+
able_node_init(&o0.n);
119+
o0.b = malloc(1024);
120+
o0.bc = 1024;
121+
122+
able_task_t o0t;
123+
memset(&o0t, 0, sizeof(o0t));
124+
o0t.f = (able_task_exec_t)term_send_exec;
125+
o0t.u = &o0;
126+
127+
able_wire_t o0w[256];
128+
memset(&o0w, 0, sizeof(o0w));
129+
130+
// host 0
131+
able_node_t h0n;
132+
able_node_init(&h0n);
133+
134+
able_port_t h0p[256];
135+
memset(h0p, 0, sizeof(h0p));
136+
able_link_t h0l[256];
137+
memset(h0l, 0, sizeof(h0l));
138+
able_host_t h0;
139+
memset(&h0, 0, sizeof(h0));
140+
h0.p = h0p;
141+
h0.pc = 256;
142+
h0.l = h0l;
143+
h0.lc = 256;
144+
h0.c.b = b;
145+
h0.c.bc = bc;
146+
h0.u = &h0n;
147+
h0.ts = 1000;
148+
149+
able_task_t h0t;
150+
memset(&h0t, 0, sizeof(h0t));
151+
h0t.f = (able_task_exec_t)able_host_exec_shim;
152+
h0t.u = &h0;
153+
154+
able_wire_t h0w[256];
155+
memset(&h0w, 0, sizeof(h0w));
156+
157+
trap_data.u = &h0;
158+
signal(SIGINT, trap);
159+
160+
// virtual network config
161+
162+
// h0.p[0]<-i0.l
163+
able_wire_bind(&h0w[1], &h0.p[0], 1, &h0n);
164+
able_wire_join(&h0w[1], &i0.l);
165+
// o0.p<-h0.l[0]
166+
able_wire_bind(&o0w[0], &o0.p, 0, &o0.n);
167+
able_wire_join(&o0w[0], &h0.l[0]);
168+
// h0.p[0]<-o0.l
169+
able_wire_bind(&h0w[0], &h0.p[0], 0, &h0n);
170+
able_wire_join(&h0w[0], &o0.l);
171+
172+
able_task_fork_exec(&i0t);
173+
able_task_fork_exec(&o0t);
174+
able_task_exec(&h0t);
175+
176+
// should not happen
177+
return 2;
178+
}

config.mk.def

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
PREFIX?=/usr/local/able
2+
BINDIR=${PREFIX}/bin
3+
INCDIR=${PREFIX}/include
4+
LIBDIR=${PREFIX}/lib
5+
MANDIR=${PREFIX}/man
6+
7+
CC=clang
8+
CFLAGS=-I${INCDIR} -g -O2 -std=c11 -pedantic -Wall -Wno-zero-length-array -Wno-gnu-label-as-value -Wno-gnu-designator -Wno-gnu-empty-struct
9+
10+
.ifdef DEBUG
11+
CFLAGS+=-DDEBUG=${DEBUG}
12+
.endif
13+
14+
.ifdef COMPAT_LINUX
15+
CFLAGS+=-DABLE_COMPAT_LINUX -D_GNU_SOURCE
16+
.endif
17+
18+
LD=${CC}
19+
LDFLAGS=-L${LIBDIR}

libable_shim.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#include <stdatomic.h>
2+
#include <pthread.h>
3+
#include <able/able.h>
4+
#include "libable_shim.h"
5+
#include <inttypes.h>
6+
#include <stdio.h>
7+
#include <string.h>
8+
#include "trap.h"
9+
10+
int
11+
able_host_wait_shim(able_host_t *host, able_edge_t *edge, const struct timespec *time) {
12+
return able_node_wait(host->u, edge, time);
13+
}
14+
15+
int
16+
able_link_post_shim(able_link_t *link, able_edge_t *edge) {
17+
return able_node_post(link->u, edge);
18+
}
19+
20+
#define P(C, Y) \
21+
fprintf(stderr, "%02"PRIX8"(%"PRId8") %"PRId64" %08"PRIX64" %"PRId64"/%"PRIX64" %"PRId64"/%"PRIX64" (%"PRIu8"); %"PRId64"/%"PRIX64" (%"PRIu8")\n", \
22+
(C)->i, \
23+
(Y), \
24+
(C)->ts, \
25+
(C)->p, \
26+
(C)->d1, (C)->d1, \
27+
(C)->d0, (C)->d0, \
28+
(C)->dp, \
29+
(C)->c0, (C)->c0, \
30+
(C)->cp);
31+
32+
int
33+
able_host_exec_shim(able_host_t *host) {
34+
for (;;) {
35+
able_host_t *h;
36+
h = trap_data.u;
37+
if (h == host) {
38+
int q;
39+
q = atomic_exchange(&trap_data.q, 0);
40+
if (q == 1) {
41+
h->c.p = 0;
42+
h->c.d0 = 0;
43+
h->c.d1 = 0;
44+
memset(h->c.d, 0, sizeof(h->c.d));
45+
h->c.dp = 0;
46+
h->c.c0 = 0;
47+
memset(h->c.c, 0, sizeof(h->c.c));
48+
h->c.cp = 0;
49+
}
50+
}
51+
int y;
52+
y = able_host_exec(host);
53+
switch (y) {
54+
case -1: // end of timeslice
55+
able_host_wait_shim(host, NULL, NULL);
56+
return y;
57+
case -2: // bad memory access
58+
case -3: // divide by zero
59+
#ifdef DEBUG
60+
P(&host->c, y);
61+
#endif
62+
host->c.p = 0;
63+
break;
64+
case -4: // illegal instruction
65+
switch (host->c.i) {
66+
case 0x85: // debug
67+
P(&host->c, y);
68+
break;
69+
default:
70+
#ifdef DEBUG
71+
P(&host->c, y);
72+
#endif
73+
host->c.p = 0;
74+
break;
75+
}
76+
break;
77+
case -5: // start of timeslice
78+
return y;
79+
}
80+
}
81+
82+
// should not happen
83+
return 1;
84+
}

libable_shim.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
int
2+
able_host_exec_shim(able_host_t *host);

0 commit comments

Comments
 (0)