symbols
This commit is contained in:
parent
f1eae1be22
commit
d6716d3112
12
Makefile
12
Makefile
|
@ -11,16 +11,16 @@ kas: kpc as/regs.lst as/k-as.py
|
|||
|
||||
DOSK = $(shell find ka -name '*.k')
|
||||
|
||||
vm/a.out: $(DOSK)
|
||||
@cd ka && ../as/k-as.py dos.k 0x100000 ../vm/a.out
|
||||
vm/a.out: $(DOSK) kas
|
||||
@cd ka && ../as/k-as.py dos.k 0x100000 ../vm/a.out ../vm/a.sym
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@cd vm && make clean --no-print-directory
|
||||
@rm -f vm/a.out vm/k.exe vm/stdout.txt as/instrs.lst
|
||||
@rm -f vm/a.out vm/a.out.sym vm/k.exe vm/stdout.txt as/instrs.lst
|
||||
|
||||
test: kas vm/a.out
|
||||
@vm/k.exe vm/a.out > vm/stdout.txt
|
||||
test: vm/a.out
|
||||
@vm/k.exe vm/a.out vm/a.sym > vm/stdout.txt
|
||||
@rm -f vm/a.out
|
||||
@echo "output:"
|
||||
@echo ">>>>>>>>"
|
||||
|
@ -29,6 +29,6 @@ test: kas vm/a.out
|
|||
@echo "<<<<<<<<"
|
||||
@echo
|
||||
|
||||
wc:
|
||||
wc: clean
|
||||
@cat $(shell find -name *.[kch]) $(shell find -name *.py) | wc -l
|
||||
|
||||
|
|
56
as/k-as.py
56
as/k-as.py
|
@ -8,11 +8,12 @@ import sys
|
|||
import subprocess
|
||||
from array import array
|
||||
from tempfile import TemporaryFile
|
||||
from collections import OrderedDict
|
||||
|
||||
WANT_DISASM = False
|
||||
|
||||
if len(sys.argv) != 4:
|
||||
print("Usage: {} (output file) (memory entry point) (source file)"
|
||||
if len(sys.argv) != 5:
|
||||
print("Usage: {} (output file) (memory entry point) (source file) (symbols file)"
|
||||
.format(sys.argv[0]))
|
||||
sys.exit(1)
|
||||
|
||||
|
@ -26,6 +27,7 @@ lst_instrs = open(os.path.join(sys.path[0], "instrs.lst"))
|
|||
|
||||
main_src = open(sys.argv[1])
|
||||
b_out = open(sys.argv[3], "wb")
|
||||
b_sym = open(sys.argv[4], "w")
|
||||
|
||||
start_addr = int(sys.argv[2], base=0)
|
||||
|
||||
|
@ -33,6 +35,7 @@ def leave():
|
|||
source.close()
|
||||
instrs.close()
|
||||
b_out.close()
|
||||
b_sym.close()
|
||||
b_data.close()
|
||||
b_text.close()
|
||||
main_src.close()
|
||||
|
@ -51,8 +54,8 @@ pregs = list()
|
|||
pinstrs = list()
|
||||
|
||||
# labels
|
||||
plabels_text = dict()
|
||||
plabels_data = dict()
|
||||
plabels_text = OrderedDict()
|
||||
plabels_data = OrderedDict()
|
||||
|
||||
# size of .data section
|
||||
pdata = 0
|
||||
|
@ -65,9 +68,6 @@ plastlabel = ''
|
|||
|
||||
# after parse() is done, pdata and ptext are never modified
|
||||
|
||||
# padding bytes between .text and .data
|
||||
pdata_pad = 0
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def name_valid(name):
|
||||
|
@ -179,6 +179,7 @@ def parse():
|
|||
|
||||
if line[0] == ' ' or line[0] == '\t':
|
||||
line = line.lstrip()
|
||||
instrs.write(hex(ptext + start_addr) + ' ')
|
||||
ptext += parse_instr(line)
|
||||
instrs.write("\n")
|
||||
|
||||
|
@ -676,19 +677,19 @@ special_syms = {
|
|||
}
|
||||
|
||||
def gentext():
|
||||
instrs.seek(0)
|
||||
|
||||
if WANT_DISASM:
|
||||
int(instrs.read())
|
||||
instrs.seek(0)
|
||||
|
||||
text_start = 0x100000
|
||||
text_start = start_addr
|
||||
data_start = text_start + ptext
|
||||
data_start += (8 - data_start % 8)
|
||||
|
||||
instrs.seek(0)
|
||||
|
||||
for _, line in enumerate(instrs):
|
||||
tok = line.strip().split()
|
||||
#print(tok)
|
||||
|
||||
if WANT_DISASM:
|
||||
print(tok)
|
||||
|
||||
tok = tok[1:]
|
||||
|
||||
for word in tok:
|
||||
if len(word) == 0:
|
||||
|
@ -722,7 +723,7 @@ def gentext():
|
|||
continue
|
||||
|
||||
if word in plabels_data:
|
||||
addr = data_start + plabels_data[word] + pdata_pad
|
||||
addr = data_start + plabels_data[word]
|
||||
b_text.write(addr.to_bytes(8, byteorder='little', signed=False))
|
||||
continue
|
||||
|
||||
|
@ -756,6 +757,28 @@ def gentext():
|
|||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def sort_by_list(dict_, list_):
|
||||
for key in list_:
|
||||
dict_.move_to_end(key)
|
||||
|
||||
def gensym():
|
||||
text_start = start_addr
|
||||
data_start = text_start + ptext
|
||||
data_start += (8 - data_start % 8)
|
||||
|
||||
for label in plabels_text:
|
||||
plabels_text[label] += text_start
|
||||
|
||||
for label in plabels_data:
|
||||
plabels_data[label] += data_start
|
||||
|
||||
plabels_all = OrderedDict(list(plabels_text.items()) + list(plabels_data.items()))
|
||||
|
||||
for key, value in sorted(plabels_all.items(), key=lambda item: item[1]):
|
||||
b_sym.write("{} {}\n".format(key, value))
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def genout():
|
||||
b_text.seek(0)
|
||||
b_data.seek(0)
|
||||
|
@ -776,5 +799,6 @@ do_includes(main_src)
|
|||
parse()
|
||||
gentext()
|
||||
genout()
|
||||
gensym()
|
||||
leave()
|
||||
sys.exit(0)
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
_start 1048576
|
||||
_start.1 1048610
|
||||
itoa 1048626
|
||||
utoa 1048652
|
||||
_itoa 1048678
|
||||
_itoa.conv 1048840
|
||||
_itoa.nondec 1048928
|
||||
_itoa.next 1048942
|
||||
_itoa.fini 1048976
|
||||
_itoa.bad 1049048
|
||||
_itoa.zero 1049086
|
||||
_doprnt 1049120
|
||||
_doprnt.main_loop 1049250
|
||||
_doprnt.print_regular 1049286
|
||||
_doprnt.check_modf 1049344
|
||||
_doprnt.modf_s 1049640
|
||||
_doprnt.print_string 1049678
|
||||
_doprnt.modf_c 1049736
|
||||
_doprnt.modf_p 1049778
|
||||
_doprnt.modf_x 1049830
|
||||
_doprnt.modf_u 1049870
|
||||
_doprnt.modf_d 1049910
|
||||
_doprnt.modf_o 1049944
|
||||
_doprnt.modf_b 1049984
|
||||
_doprnt.print_number 1050024
|
||||
_doprnt.print_itoa_buf 1050084
|
||||
_doprnt.modf_percent 1050156
|
||||
_doprnt.bad_modifier 1050194
|
||||
_doprnt.nullstring 1050258
|
||||
_doprnt.epilogue 1050426
|
||||
_doprnt.doput 1050512
|
||||
putc 1050568
|
||||
printf 1050586
|
||||
print 1050644
|
||||
print.1 1050658
|
||||
print.2 1050702
|
||||
print_n 1050706
|
||||
print_n.1 1050714
|
||||
strnlen 1050742
|
||||
strlen 1050784
|
||||
strrev 1050810
|
||||
strrev.2 1050878
|
||||
strrev2 1050938
|
||||
strrev2.2 1050992
|
||||
strrev2.3 1051044
|
||||
strcpy 1051048
|
||||
strncpy 1051074
|
||||
strnzcpy 1051098
|
||||
strnzcpy.1 1051136
|
||||
strcmp 1051154
|
||||
strncmp 1051180
|
||||
strchrnul 1051242
|
||||
strchr 1051276
|
||||
RFS.GetMaxIdx 1051336
|
||||
RFS.GetUsage 1051360
|
||||
RFS.GetCurIdx 1051384
|
||||
RFS.GetLeastAvail 1051408
|
||||
RFS.IsFrameActive 1051432
|
||||
RFS.ActivateFrame 1051456
|
||||
RFS.DeactivateFrame 1051480
|
||||
RFS.CopyFrame 1051504
|
||||
RFS.MoveFrame 1051528
|
||||
RFS.SwitchFrame 1051552
|
||||
RFS.LoadArgs 1051576
|
||||
RFS.LoadReg 1051600
|
||||
RFS.StoreReg 1051624
|
||||
IDT.AddHandler 1051648
|
||||
IDT.DelHandler 1051672
|
||||
IDT.QueryHandler 1051696
|
||||
IDT.DoneHandling 1051716
|
||||
MEM.GetMemOff 1051740
|
||||
MEM.GetMemSize 1051764
|
||||
cpudev_test 1051788
|
||||
trap0_test 1052008
|
||||
showoff 1052080
|
||||
printf_test 1052180
|
||||
strchr_test 1052332
|
||||
bswap_test 1052396
|
||||
ramdev_test 1052466
|
||||
movzx_test 1052502
|
||||
itoa_test 1052600
|
||||
devtest 1052764
|
||||
str_test 1052848
|
||||
main 1053184
|
||||
errno 1053208
|
||||
trap0_test.msg 1053216
|
||||
printf_test.fmt 1053239
|
||||
printf_test.str 1053287
|
||||
strchr_test.str 1053295
|
||||
itoa_test.buf 1053311
|
||||
devtest.buf 1053351
|
||||
str_test.msg 1053391
|
||||
str_test.buf1 1053407
|
||||
str_test.buf2 1053447
|
|
@ -79,6 +79,7 @@ void enable_stdin_echoing(void);
|
|||
void disable_stdin_echoing(void);
|
||||
|
||||
#include <pc/mem.h>
|
||||
#include <pc/sym.h>
|
||||
#include <pc/regs.h>
|
||||
#include <pc/decd.h>
|
||||
#include <pc/except.h>
|
||||
|
|
31
vm/pc/decd.c
31
vm/pc/decd.c
|
@ -181,30 +181,27 @@ void decode(ctx_t *ctx)
|
|||
|
||||
if (w1 >= NINSTRS)
|
||||
{
|
||||
illmsg = "No such INSTR";
|
||||
goto ill;
|
||||
_except(ctx, E_ILL, "No such INSTR: 0x%hX", w1);
|
||||
}
|
||||
|
||||
in = &ctx->i[w1];
|
||||
|
||||
if (nomore)
|
||||
goto skip_w2;
|
||||
if (!nomore)
|
||||
{
|
||||
//
|
||||
// Process second word
|
||||
//
|
||||
|
||||
//
|
||||
// Process second word
|
||||
//
|
||||
w2 = ctx->get(ctx);
|
||||
|
||||
w2 = ctx->get(ctx);
|
||||
// REP and COND
|
||||
rep = !!(w2 & PREF_REP);
|
||||
cond = (w2 & BITS_COND) >> COND_SHIFT;
|
||||
|
||||
// REP and COND
|
||||
rep = !!(w2 & PREF_REP);
|
||||
cond = (w2 & BITS_COND) >> COND_SHIFT;
|
||||
|
||||
// F1 and F2
|
||||
f1 = (w2 >> F1_SHIFT) & Fx_MASK;
|
||||
f2 = w2 & Fx_MASK;
|
||||
|
||||
skip_w2:
|
||||
// F1 and F2
|
||||
f1 = (w2 >> F1_SHIFT) & Fx_MASK;
|
||||
f2 = w2 & Fx_MASK;
|
||||
}
|
||||
|
||||
//
|
||||
// Deal with operand 1
|
||||
|
|
111
vm/pc/dump.c
111
vm/pc/dump.c
|
@ -35,37 +35,12 @@ void dump_instr(ctx_t *ctx,
|
|||
|
||||
log("%s", in->name);
|
||||
|
||||
#if _ATT_STYLE == 1
|
||||
if (p1 || p2)
|
||||
{
|
||||
int l1 = 8, l2 = 8;
|
||||
|
||||
if (p1 && ACC_IS_MEM(p1)) {
|
||||
l1 = p1->mlen;
|
||||
}
|
||||
|
||||
if (p2 && ACC_IS_MEM(p2)) {
|
||||
l2 = p2->mlen;
|
||||
}
|
||||
|
||||
log("%c", getmempref(l1<l2 ? l1 : l2));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rep)
|
||||
#if _ATT_STYLE == 0
|
||||
log(".rep");
|
||||
#else
|
||||
log("$rep");
|
||||
#endif
|
||||
|
||||
if (cond)
|
||||
{
|
||||
#if _ATT_STYLE == 0
|
||||
log(".");
|
||||
#else
|
||||
log("?");
|
||||
#endif
|
||||
|
||||
if (cond & (1 << 4))
|
||||
{
|
||||
|
@ -78,40 +53,27 @@ void dump_instr(ctx_t *ctx,
|
|||
log("%s", cond_suffixes[cond]);
|
||||
}
|
||||
|
||||
if (!rep
|
||||
#if _ATT_STYLE == 1
|
||||
&& cond != CD_CXZ
|
||||
#endif
|
||||
) log("\t\t");
|
||||
if (!rep) log("\t\t");
|
||||
|
||||
else
|
||||
log("\t");
|
||||
|
||||
if (p1)
|
||||
{
|
||||
#if _ATT_STYLE == 0
|
||||
dump_acc(ctx, p1);
|
||||
if (p2) {
|
||||
log(", ");
|
||||
dump_acc(ctx, p2);
|
||||
}
|
||||
#else
|
||||
if (p2) {
|
||||
dump_acc(ctx, p2);
|
||||
log(", ");
|
||||
}
|
||||
dump_acc(ctx, p1);
|
||||
#endif
|
||||
}
|
||||
|
||||
log("\n");
|
||||
}
|
||||
|
||||
#if _ATT_STYLE == 0
|
||||
|
||||
void dump_acc(ctx_t *ctx, acc_t *p)
|
||||
{
|
||||
uint mfmt;
|
||||
sym_t *sym;
|
||||
|
||||
if (p->type == A_REG)
|
||||
log("%s", ctx->r[p->reg].name);
|
||||
|
@ -122,7 +84,14 @@ void dump_acc(ctx_t *ctx, acc_t *p)
|
|||
log("%lu", p->val);
|
||||
|
||||
else
|
||||
log("0x%lX", p->val);
|
||||
{
|
||||
sym = find_sym_by_addr(p->val);
|
||||
|
||||
if (sym)
|
||||
log("$%s(0x%lX)", sym->name, sym->addr);
|
||||
else
|
||||
log("0x%lX", p->val);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
|
@ -167,63 +136,3 @@ void dump_acc(ctx_t *ctx, acc_t *p)
|
|||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void dump_acc(ctx_t *ctx, acc_t *p)
|
||||
{
|
||||
uint mfmt;
|
||||
|
||||
if (p->type == A_REG)
|
||||
log("%%%s", ctx->r[p->reg].name);
|
||||
|
||||
else if (p->type == A_IMM64)
|
||||
{
|
||||
if (p->val < 0xA)
|
||||
log("$%lu", p->val);
|
||||
|
||||
else
|
||||
log("$0x%lX", p->val);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
mfmt = p->type & AM_MFMT_MASK;
|
||||
|
||||
if (mfmt == AM_IMM64)
|
||||
log("($0x%lX)", p->addr);
|
||||
|
||||
else if (mfmt == AM_RR)
|
||||
{
|
||||
if (p->reg1 && p->reg2)
|
||||
log("(%%%s,%%%s)", ctx->r[p->reg1].name, ctx->r[p->reg2].name);
|
||||
|
||||
else log("(%%%s)", ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
|
||||
}
|
||||
|
||||
else if (mfmt == AM_RRI)
|
||||
{
|
||||
if (p->reg1 && p->reg2)
|
||||
log("%hd(%%%s,%%%s)", p->imm2, ctx->r[p->reg1].name,
|
||||
ctx->r[p->reg2].name);
|
||||
|
||||
else log("%hd(%%%s)", p->imm2,
|
||||
ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
|
||||
}
|
||||
|
||||
else if (mfmt == AM_RRII)
|
||||
{
|
||||
if (p->reg1)
|
||||
log("%hd(%s,%s,$%u)", p->imm2,
|
||||
ctx->r[p->reg1].name,
|
||||
ctx->r[p->reg2].name,
|
||||
p->imm1);
|
||||
else
|
||||
log("%hd(*,%s,$%u)", p->imm2,
|
||||
ctx->r[p->reg2].name,
|
||||
p->imm1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
14
vm/pc/main.c
14
vm/pc/main.c
|
@ -14,14 +14,6 @@ ushort bget(ctx_t *ctx)
|
|||
{
|
||||
ulong addr = rip + cr1;
|
||||
|
||||
/*
|
||||
if (addr % 2) {
|
||||
_except(ctx, E_ALI, "Misaligned RIP and/or CR1: "
|
||||
"rip=0x%lX cr1=0x%lX",
|
||||
rip, cr1);
|
||||
}
|
||||
*/
|
||||
|
||||
if (addr2real(addr) >= ctx->mz) {
|
||||
_except(ctx, E_ACC, "Executing out of memory: "
|
||||
"rip=0x%lX cr1=0x%lX",
|
||||
|
@ -30,6 +22,8 @@ ushort bget(ctx_t *ctx)
|
|||
|
||||
ushort c = ctx->mp[addr2real(addr)];
|
||||
|
||||
//log("bget 0x%lX: 0x%lX\n", addr, c);
|
||||
|
||||
rip += 2;
|
||||
|
||||
return c;
|
||||
|
@ -99,11 +93,13 @@ int main(int argc, char **argv)
|
|||
//
|
||||
// Load program
|
||||
//
|
||||
if (argc < 2) {
|
||||
if (argc < 3) {
|
||||
log("Not enough arguments\n");
|
||||
exit(-3);
|
||||
}
|
||||
|
||||
create_symtab(argv[2]);
|
||||
|
||||
fwfile = fopen(argv[1], "rb");
|
||||
|
||||
if (!fwfile) {
|
||||
|
|
|
@ -145,6 +145,8 @@ void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
|||
GETREAL();
|
||||
CHK_RANGE();
|
||||
|
||||
// log("writemem: 0x%lX: 0x%lX (%d)\n", addr, val, len);
|
||||
|
||||
switch (len) {
|
||||
case 1: writemem8(ctx, val, real, addr); break;
|
||||
case 2: writemem16(ctx, val, real, addr); break;
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
// The OS/K Team licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#include <pc/arch.h>
|
||||
|
||||
sym_t symtab[SYMTAB_LEN] = { 0 };
|
||||
|
||||
int create_symtab(const char *name)
|
||||
{
|
||||
FILE *tab = fopen(name, "r");
|
||||
ulong addr, prev_addr = 0;
|
||||
char buf[SYMLEN_MAX] = { 0 };
|
||||
size_t it = 0;
|
||||
|
||||
if (!tab)
|
||||
{
|
||||
log("Couldn't open symtab\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fscanf(tab, "%s %lu\n", buf, &addr) > 0 && it < SYMTAB_LEN)
|
||||
{
|
||||
// log("SYM: '%.*s' '%lu'\n", SYMLEN_MAX, buf, addr);
|
||||
|
||||
if (prev_addr >= addr)
|
||||
{
|
||||
log("Symbol addresses in symbol table not in increasing order\n");
|
||||
log("Previous symbol: '%s' '%lu'\n", symtab[it-1].name, prev_addr);
|
||||
log("Current symbol: '%s' '%lu'\n", buf, addr);
|
||||
exit(-55);
|
||||
}
|
||||
|
||||
prev_addr = addr;
|
||||
|
||||
symtab[it].addr = addr;
|
||||
strcpy(symtab[it].name, buf);
|
||||
it++;
|
||||
}
|
||||
|
||||
fclose(tab);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
sym_t *find_sym_by_addr(ulong addr)
|
||||
{
|
||||
ulong it;
|
||||
sym_t *sym;
|
||||
|
||||
for (it = 0; it < SYMTAB_LEN; it++)
|
||||
{
|
||||
sym = &symtab[it];
|
||||
|
||||
if (sym->addr == addr)
|
||||
return sym;
|
||||
|
||||
// Addresses in symtab are in increasing order
|
||||
if (sym->addr == 0 || sym->addr > addr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// The OS/K Team licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#define SYMLEN_MAX 32
|
||||
#define SYMTAB_LEN 4096
|
||||
|
||||
typedef struct sym_t sym_t;
|
||||
|
||||
struct sym_t
|
||||
{
|
||||
ulong addr;
|
||||
char name[SYMLEN_MAX];
|
||||
};
|
||||
|
||||
extern sym_t symtab[SYMTAB_LEN];
|
||||
|
||||
int create_symtab(const char *name);
|
||||
sym_t *find_sym_by_addr(ulong addr);
|
||||
|
Loading…
Reference in New Issue