mirror of
https://gitlab.os-k.eu/os-k-team/kvisc.git
synced 2023-08-25 14:05:46 +02:00
trace
This commit is contained in:
parent
6f5a453fec
commit
6f8a5d1f76
@ -5,6 +5,5 @@
|
|||||||
; Main function
|
; Main function
|
||||||
;
|
;
|
||||||
main:
|
main:
|
||||||
call showoff
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@ -10,14 +10,17 @@ FLAGS=-O2 -g -Wall -fno-builtin-log -I.
|
|||||||
dv_src = $(shell ls dv/*.c)
|
dv_src = $(shell ls dv/*.c)
|
||||||
in_src = $(shell ls in/*.c)
|
in_src = $(shell ls in/*.c)
|
||||||
pc_src = $(shell ls pc/*.c)
|
pc_src = $(shell ls pc/*.c)
|
||||||
|
cn_src = $(shell ls cn/*.c)
|
||||||
|
|
||||||
obj = $(patsubst %.c,$(OBJDIR)/%.o,$(dv_src))
|
obj = $(patsubst %.c,$(OBJDIR)/%.o,$(dv_src))
|
||||||
obj += $(patsubst %.c,$(OBJDIR)/%.o,$(in_src))
|
obj += $(patsubst %.c,$(OBJDIR)/%.o,$(in_src))
|
||||||
obj += $(patsubst %.c,$(OBJDIR)/%.o,$(pc_src))
|
obj += $(patsubst %.c,$(OBJDIR)/%.o,$(pc_src))
|
||||||
|
obj += $(patsubst %.c,$(OBJDIR)/%.o,$(cn_src))
|
||||||
|
|
||||||
dep = $(patsubst %.c,$(OBJDIR)/%.d,$(dv_src))
|
dep = $(patsubst %.c,$(OBJDIR)/%.d,$(dv_src))
|
||||||
dep += $(patsubst %.c,$(OBJDIR)/%.d,$(in_src))
|
dep += $(patsubst %.c,$(OBJDIR)/%.d,$(in_src))
|
||||||
dep += $(patsubst %.c,$(OBJDIR)/%.d,$(pc_src))
|
dep += $(patsubst %.c,$(OBJDIR)/%.d,$(pc_src))
|
||||||
|
dep += $(patsubst %.c,$(OBJDIR)/%.d,$(cn_src))
|
||||||
|
|
||||||
# Color codes
|
# Color codes
|
||||||
CL='\033[0;32m'
|
CL='\033[0;32m'
|
||||||
@ -51,6 +54,6 @@ clean:
|
|||||||
@rm -f $(OBJDIR)/*/*.d
|
@rm -f $(OBJDIR)/*/*.d
|
||||||
|
|
||||||
k.exe: in/instrs.lst $(obj)
|
k.exe: in/instrs.lst $(obj)
|
||||||
@gcc -O2 -Wall $(obj) -o k.exe
|
@gcc -O2 -lSDL2 -Wall $(obj) -o k.exe
|
||||||
@echo ${CL2}[$@] ${CL}made successfully.${CL3}
|
@echo ${CL2}[$@] ${CL}made successfully.${CL3}
|
||||||
|
|
||||||
|
20
vm/a.sym
20
vm/a.sym
@ -82,13 +82,13 @@ itoa_test 1052600
|
|||||||
devtest 1052764
|
devtest 1052764
|
||||||
str_test 1052848
|
str_test 1052848
|
||||||
main 1053184
|
main 1053184
|
||||||
errno 1053208
|
errno 1053192
|
||||||
trap0_test.msg 1053216
|
trap0_test.msg 1053200
|
||||||
printf_test.fmt 1053239
|
printf_test.fmt 1053223
|
||||||
printf_test.str 1053287
|
printf_test.str 1053271
|
||||||
strchr_test.str 1053295
|
strchr_test.str 1053279
|
||||||
itoa_test.buf 1053311
|
itoa_test.buf 1053295
|
||||||
devtest.buf 1053351
|
devtest.buf 1053335
|
||||||
str_test.msg 1053391
|
str_test.msg 1053375
|
||||||
str_test.buf1 1053407
|
str_test.buf1 1053391
|
||||||
str_test.buf2 1053447
|
str_test.buf2 1053431
|
||||||
|
16
vm/cn/console.c
Normal file
16
vm/cn/console.c
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// 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 <cn/console.h>
|
||||||
|
|
||||||
|
void console_init(ctx_t *ctx)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
||||||
|
{
|
||||||
|
log("Couldn't initialize SDL: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480, SDL_WINDOW_SHOWN);*/
|
||||||
|
}
|
||||||
|
|
10
vm/cn/console.h
Normal file
10
vm/cn/console.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// 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>
|
||||||
|
|
||||||
|
//#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
|
||||||
|
void console_init(ctx_t *ctx);
|
||||||
|
|
258
vm/in/INSTRS
258
vm/in/INSTRS
@ -366,129 +366,21 @@ enter i
|
|||||||
#
|
#
|
||||||
leave
|
leave
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#
|
||||||
# String manipulation instructions #
|
# PUSH value onto stack
|
||||||
#---------------------------------------------------------------------------#
|
#
|
||||||
|
# RSP = RSP - 8
|
||||||
|
# *RSP = $1
|
||||||
|
#
|
||||||
|
push rim
|
||||||
|
|
||||||
#
|
#
|
||||||
# Store value into string (STOSx)
|
# POP value from stack
|
||||||
#
|
#
|
||||||
# [%1] = $2
|
# $1 = *RSP
|
||||||
# IF (DF == 0) THEN
|
# RSP = RSP + 8
|
||||||
# %str = %str + sizeof(x)
|
|
||||||
# ELSE
|
|
||||||
# %str = %str - sizeof(x)
|
|
||||||
# FI
|
|
||||||
#
|
#
|
||||||
# When no parameters are given, %str = RDI and $val = RAX
|
pop rm
|
||||||
# When one parameter is given, %str = RDI and $val = $1
|
|
||||||
# When two parameters are given, %str = $1 and $val = $2
|
|
||||||
#
|
|
||||||
stosb r rim
|
|
||||||
stosw r rim
|
|
||||||
stosl r rim
|
|
||||||
stosq r rim
|
|
||||||
|
|
||||||
#
|
|
||||||
# Load value from string (LODSx)
|
|
||||||
#
|
|
||||||
# $1 = [%2]
|
|
||||||
# IF (DF == 0) THEN
|
|
||||||
# %str = %str + sizeof(x)
|
|
||||||
# ELSE
|
|
||||||
# %str = %str - sizeof(x)
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
# Preserves CF, OF and SF
|
|
||||||
# Sets ZF according to the loaded value
|
|
||||||
#
|
|
||||||
lodsb r r
|
|
||||||
lodsw r r
|
|
||||||
lodsl r r
|
|
||||||
lodsq r r
|
|
||||||
|
|
||||||
#
|
|
||||||
# Scan string for a particular value (SCASx)
|
|
||||||
#
|
|
||||||
# CMP([%1], $2)
|
|
||||||
#
|
|
||||||
# IF ([%1] == 0) THEN
|
|
||||||
# ZF = 1
|
|
||||||
# ELIF (ZF == 0) THEN
|
|
||||||
# IF (DF == 0) THEN
|
|
||||||
# %1 = %1 + sizeof(x)
|
|
||||||
# ELSE
|
|
||||||
# %1 = %1 - sizeof(x)
|
|
||||||
# FI
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
# Sets CF, OF and SF according to the result of the comparison
|
|
||||||
# Sets ZF according to whether [%1] and $2 are equal, OR if [%1] is null
|
|
||||||
#
|
|
||||||
# Notes:
|
|
||||||
# - Does not move past the value when found
|
|
||||||
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
|
|
||||||
#
|
|
||||||
scasb r rim
|
|
||||||
scasw r rim
|
|
||||||
scasl r rim
|
|
||||||
scasq r rim
|
|
||||||
|
|
||||||
#
|
|
||||||
# Compare bytes in strings (CMPSx)
|
|
||||||
#
|
|
||||||
# CMP([%1], [%2])
|
|
||||||
#
|
|
||||||
# IF (DF == 0) THEN
|
|
||||||
# %1 = %1 + sizeof(x)
|
|
||||||
# %2 = %2 + sizeof(x)
|
|
||||||
# ELSE
|
|
||||||
# %1 = %1 - sizeof(x)
|
|
||||||
# %2 = %2 - sizeof(x)
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
# Sets CF, OF, ZF and SF according to the result of the comparison
|
|
||||||
#
|
|
||||||
# Moves past the compared values in any case!
|
|
||||||
#
|
|
||||||
cmpsb r r
|
|
||||||
cmpsw r r
|
|
||||||
cmpsl r r
|
|
||||||
cmpsq r r
|
|
||||||
|
|
||||||
#
|
|
||||||
# Safe compare bytes in strings (CMPZSx)
|
|
||||||
#
|
|
||||||
# Behaves precisely like CMPSx, except in the following case:
|
|
||||||
# - If both [%1] and [%2] are zero, clears ZF (indicating NOT EQUAL)
|
|
||||||
#
|
|
||||||
# This prevents 'CMPZSx.REP.Z' from looping infinitely when both strings
|
|
||||||
# have the exact same content; this allows for short strcmp's
|
|
||||||
#
|
|
||||||
cmpzsb r r
|
|
||||||
cmpzsw r r
|
|
||||||
cmpzsl r r
|
|
||||||
cmpzsq r r
|
|
||||||
|
|
||||||
#
|
|
||||||
# Move value from string to string (MOVSx)
|
|
||||||
#
|
|
||||||
# [%1] = [%1]
|
|
||||||
# IF (DF == 0) THEN
|
|
||||||
# %1 = %1 + sizeof(x)
|
|
||||||
# %2 = %2 + sizeof(x)
|
|
||||||
# ELSE
|
|
||||||
# %1 = %1 - sizeof(x)
|
|
||||||
# %2 = %2 - sizeof(x)
|
|
||||||
# FI
|
|
||||||
#
|
|
||||||
# Preserves CF, OF and SF
|
|
||||||
# Sets ZF according to the moved value
|
|
||||||
#
|
|
||||||
movsb r r
|
|
||||||
movsw r r
|
|
||||||
movsl r r
|
|
||||||
movsq r r
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
# Supervisor only instructions #
|
# Supervisor only instructions #
|
||||||
@ -683,34 +575,128 @@ clr
|
|||||||
cla
|
cla
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
# Deprecated instruction #
|
# String manipulation instructions #
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
#
|
#
|
||||||
# PUSH value onto stack
|
# Store value into string (STOSx)
|
||||||
#
|
#
|
||||||
# RSP = RSP - 8
|
# [%1] = $2
|
||||||
# *RSP = $1
|
# IF (DF == 0) THEN
|
||||||
|
# %str = %str + sizeof(x)
|
||||||
|
# ELSE
|
||||||
|
# %str = %str - sizeof(x)
|
||||||
|
# FI
|
||||||
#
|
#
|
||||||
# Throws:
|
# When no parameters are given, %str = RDI and $val = RAX
|
||||||
# #STA if RBP MOD 8 > 0
|
# When one parameter is given, %str = RDI and $val = $1
|
||||||
# #STA if RSP MOD 8 > 0
|
# When two parameters are given, %str = $1 and $val = $2
|
||||||
# #STU if RSP > RBP
|
|
||||||
#
|
#
|
||||||
!push rim
|
stosb r rim
|
||||||
|
stosw r rim
|
||||||
|
stosl r rim
|
||||||
|
stosq r rim
|
||||||
|
|
||||||
#
|
#
|
||||||
# POP value from stack
|
# Load value from string (LODSx)
|
||||||
#
|
#
|
||||||
# $1 = *RSP
|
# $1 = [%2]
|
||||||
# RSP = RSP + 8
|
# IF (DF == 0) THEN
|
||||||
|
# %str = %str + sizeof(x)
|
||||||
|
# ELSE
|
||||||
|
# %str = %str - sizeof(x)
|
||||||
|
# FI
|
||||||
#
|
#
|
||||||
# Throws:
|
# Preserves CF, OF and SF
|
||||||
# #STA if RBP MOD 8 > 0
|
# Sets ZF according to the loaded value
|
||||||
# #STA if RSP MOD 8 > 0
|
|
||||||
# #STU if RSP >= RBP
|
|
||||||
#
|
#
|
||||||
!pop rm
|
lodsb r r
|
||||||
|
lodsw r r
|
||||||
|
lodsl r r
|
||||||
|
lodsq r r
|
||||||
|
|
||||||
|
#
|
||||||
|
# Scan string for a particular value (SCASx)
|
||||||
|
#
|
||||||
|
# CMP([%1], $2)
|
||||||
|
#
|
||||||
|
# IF ([%1] == 0) THEN
|
||||||
|
# ZF = 1
|
||||||
|
# ELIF (ZF == 0) THEN
|
||||||
|
# IF (DF == 0) THEN
|
||||||
|
# %1 = %1 + sizeof(x)
|
||||||
|
# ELSE
|
||||||
|
# %1 = %1 - sizeof(x)
|
||||||
|
# FI
|
||||||
|
# FI
|
||||||
|
#
|
||||||
|
# Sets CF, OF and SF according to the result of the comparison
|
||||||
|
# Sets ZF according to whether [%1] and $2 are equal, OR if [%1] is null
|
||||||
|
#
|
||||||
|
# Notes:
|
||||||
|
# - Does not move past the value when found
|
||||||
|
# - 'SCASB.REP.NZ reg ch' is a short 'strchnul()'
|
||||||
|
#
|
||||||
|
scasb r rim
|
||||||
|
scasw r rim
|
||||||
|
scasl r rim
|
||||||
|
scasq r rim
|
||||||
|
|
||||||
|
#
|
||||||
|
# Compare bytes in strings (CMPSx)
|
||||||
|
#
|
||||||
|
# CMP([%1], [%2])
|
||||||
|
#
|
||||||
|
# IF (DF == 0) THEN
|
||||||
|
# %1 = %1 + sizeof(x)
|
||||||
|
# %2 = %2 + sizeof(x)
|
||||||
|
# ELSE
|
||||||
|
# %1 = %1 - sizeof(x)
|
||||||
|
# %2 = %2 - sizeof(x)
|
||||||
|
# FI
|
||||||
|
#
|
||||||
|
# Sets CF, OF, ZF and SF according to the result of the comparison
|
||||||
|
#
|
||||||
|
# Moves past the compared values in any case!
|
||||||
|
#
|
||||||
|
cmpsb r r
|
||||||
|
cmpsw r r
|
||||||
|
cmpsl r r
|
||||||
|
cmpsq r r
|
||||||
|
|
||||||
|
#
|
||||||
|
# Safe compare bytes in strings (CMPZSx)
|
||||||
|
#
|
||||||
|
# Behaves precisely like CMPSx, except in the following case:
|
||||||
|
# - If both [%1] and [%2] are zero, clears ZF (indicating NOT EQUAL)
|
||||||
|
#
|
||||||
|
# This prevents 'CMPZSx.REP.Z' from looping infinitely when both strings
|
||||||
|
# have the exact same content; this allows for short strcmp's
|
||||||
|
#
|
||||||
|
cmpzsb r r
|
||||||
|
cmpzsw r r
|
||||||
|
cmpzsl r r
|
||||||
|
cmpzsq r r
|
||||||
|
|
||||||
|
#
|
||||||
|
# Move value from string to string (MOVSx)
|
||||||
|
#
|
||||||
|
# [%1] = [%1]
|
||||||
|
# IF (DF == 0) THEN
|
||||||
|
# %1 = %1 + sizeof(x)
|
||||||
|
# %2 = %2 + sizeof(x)
|
||||||
|
# ELSE
|
||||||
|
# %1 = %1 - sizeof(x)
|
||||||
|
# %2 = %2 - sizeof(x)
|
||||||
|
# FI
|
||||||
|
#
|
||||||
|
# Preserves CF, OF and SF
|
||||||
|
# Sets ZF according to the moved value
|
||||||
|
#
|
||||||
|
movsb r r
|
||||||
|
movsw r r
|
||||||
|
movsl r r
|
||||||
|
movsq r r
|
||||||
|
|
||||||
#---------------------------------------------------------------------------#
|
#---------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
|
|
||||||
IMPL_START_0(break)
|
IMPL_START_0(break)
|
||||||
{
|
{
|
||||||
log("\nExecuting BREAK INSTR\n");
|
trace("\nExecuting BREAK INSTR\n");
|
||||||
dumpregs(ctx);
|
dumpregs(ctx);
|
||||||
|
|
||||||
getchar();
|
getchar();
|
||||||
log("Resuming execution\n");
|
trace("Resuming execution\n");
|
||||||
}
|
}
|
||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ IMPL_END;
|
|||||||
|
|
||||||
IMPL_START_0(cpuid)
|
IMPL_START_0(cpuid)
|
||||||
{
|
{
|
||||||
|
rax = rdx = 0;
|
||||||
}
|
}
|
||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
@ -49,8 +50,8 @@ IMPL_OUT;
|
|||||||
|
|
||||||
IMPL_START_1(prn)
|
IMPL_START_1(prn)
|
||||||
{
|
{
|
||||||
if (p1->mlen > 1) {
|
if (p1->mlen > 4) {
|
||||||
log("prn warning: large access size\n");
|
trace("prn warning: large access size\n");
|
||||||
}
|
}
|
||||||
putchar((int)v1);
|
putchar((int)v1);
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
#include <in/instrs.h>
|
#include <in/instrs.h>
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
IMPL_START_1(trap)
|
IMPL_START_1(trap)
|
||||||
{
|
{
|
||||||
if (v1 > 255)
|
if (v1 > 255)
|
||||||
@ -14,7 +12,6 @@ IMPL_START_1(trap)
|
|||||||
}
|
}
|
||||||
IMPL_END;
|
IMPL_END;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
// XXX more checks
|
// XXX more checks
|
||||||
|
|
||||||
|
@ -32,7 +32,8 @@ typedef struct acc_t acc_t;
|
|||||||
typedef struct arch_t arch_t;
|
typedef struct arch_t arch_t;
|
||||||
typedef struct dev_t dev_t;
|
typedef struct dev_t dev_t;
|
||||||
|
|
||||||
void log(const char *, ...);
|
void logerr(const char *, ...);
|
||||||
|
void trace(const char *, ...);
|
||||||
void vlog(const char *, va_list);
|
void vlog(const char *, va_list);
|
||||||
|
|
||||||
#define KARCH_MAJOR 0
|
#define KARCH_MAJOR 0
|
||||||
@ -69,6 +70,8 @@ struct ctx_t
|
|||||||
|
|
||||||
#define R(X) ctx->rf[X]
|
#define R(X) ctx->rf[X]
|
||||||
|
|
||||||
|
void die(int code) __attribute__((__noreturn__));
|
||||||
|
|
||||||
void dumpregs(ctx_t *);
|
void dumpregs(ctx_t *);
|
||||||
void dumpinstr(ctx_t *, ulong, uint, ushort, acc_t *, acc_t *);
|
void dumpinstr(ctx_t *, ulong, uint, ushort, acc_t *, acc_t *);
|
||||||
void dumpmem(ctx_t *, ulong, ulong);
|
void dumpmem(ctx_t *, ulong, ulong);
|
||||||
@ -85,6 +88,7 @@ void disable_stdin_echoing(void);
|
|||||||
#include <pc/except.h>
|
#include <pc/except.h>
|
||||||
#include <in/arch_i.h>
|
#include <in/arch_i.h>
|
||||||
|
|
||||||
|
extern ctx_t main_ctx;
|
||||||
extern reg_t arch_r[NREGS];
|
extern reg_t arch_r[NREGS];
|
||||||
extern instr_t arch_i[NINSTRS];
|
extern instr_t arch_i[NINSTRS];
|
||||||
|
|
||||||
|
@ -162,6 +162,12 @@ void decode(ctx_t *ctx)
|
|||||||
|
|
||||||
ulong pc = rip;
|
ulong pc = rip;
|
||||||
|
|
||||||
|
/*
|
||||||
|
sym_t *sym = find_sym_by_addr(pc);
|
||||||
|
if (sym)
|
||||||
|
trace("0x%lX: %s:\n", pc, sym->name);
|
||||||
|
*/
|
||||||
|
|
||||||
// Instruction counter
|
// Instruction counter
|
||||||
ctx->ninstrs++;
|
ctx->ninstrs++;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ int devinitall(ctx_t *ctx)
|
|||||||
size_t it;
|
size_t it;
|
||||||
|
|
||||||
for (it = 0; arch_d[it] != NULL; it++) {
|
for (it = 0; arch_d[it] != NULL; it++) {
|
||||||
// log("Adding device %s\n", arch_d[it]->name);
|
// trace("Adding device %s\n", arch_d[it]->name);
|
||||||
if (devinit(ctx, arch_d[it]) < 0)
|
if (devinit(ctx, arch_d[it]) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
25
vm/pc/die.c
Normal file
25
vm/pc/die.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// 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/dev.h>
|
||||||
|
|
||||||
|
void die(int code)
|
||||||
|
{
|
||||||
|
dying = 1;
|
||||||
|
|
||||||
|
enable_stdin_echoing();
|
||||||
|
|
||||||
|
if (main_ctx.mp)
|
||||||
|
free(main_ctx.mp);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Shut down devices
|
||||||
|
//
|
||||||
|
if (devfiniall(&main_ctx) < 0)
|
||||||
|
{
|
||||||
|
logerr("Couldn't deinitialize devices\n");
|
||||||
|
exit(-100 - code);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(code);
|
||||||
|
}
|
46
vm/pc/dump.c
46
vm/pc/dump.c
@ -28,46 +28,46 @@ void dump_instr(ctx_t *ctx,
|
|||||||
uint cond,
|
uint cond,
|
||||||
ulong pc)
|
ulong pc)
|
||||||
{
|
{
|
||||||
log("0x%lX:\t", pc);
|
trace("0x%lX:\t", pc);
|
||||||
|
|
||||||
if (lock)
|
if (lock)
|
||||||
log("lock");
|
trace("lock");
|
||||||
|
|
||||||
log("%s", in->name);
|
trace("%s", in->name);
|
||||||
|
|
||||||
if (rep)
|
if (rep)
|
||||||
log(".rep");
|
trace(".rep");
|
||||||
|
|
||||||
if (cond)
|
if (cond)
|
||||||
{
|
{
|
||||||
log(".");
|
trace(".");
|
||||||
|
|
||||||
if (cond & (1 << 4))
|
if (cond & (1 << 4))
|
||||||
{
|
{
|
||||||
cond &= ~(1 << 4);
|
cond &= ~(1 << 4);
|
||||||
log("n");
|
trace("n");
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(cond <= sizeof(cond_suffixes)/sizeof(char *));
|
assert(cond <= sizeof(cond_suffixes)/sizeof(char *));
|
||||||
|
|
||||||
log("%s", cond_suffixes[cond]);
|
trace("%s", cond_suffixes[cond]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rep) log("\t\t");
|
if (!rep) trace("\t\t");
|
||||||
|
|
||||||
else
|
else
|
||||||
log("\t");
|
trace("\t");
|
||||||
|
|
||||||
if (p1)
|
if (p1)
|
||||||
{
|
{
|
||||||
dump_acc(ctx, p1);
|
dump_acc(ctx, p1);
|
||||||
if (p2) {
|
if (p2) {
|
||||||
log(", ");
|
trace(", ");
|
||||||
dump_acc(ctx, p2);
|
dump_acc(ctx, p2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log("\n");
|
trace("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump_acc(ctx_t *ctx, acc_t *p)
|
void dump_acc(ctx_t *ctx, acc_t *p)
|
||||||
@ -76,60 +76,60 @@ void dump_acc(ctx_t *ctx, acc_t *p)
|
|||||||
sym_t *sym;
|
sym_t *sym;
|
||||||
|
|
||||||
if (p->type == A_REG)
|
if (p->type == A_REG)
|
||||||
log("%s", ctx->r[p->reg].name);
|
trace("%s", ctx->r[p->reg].name);
|
||||||
|
|
||||||
else if (p->type == A_IMM64)
|
else if (p->type == A_IMM64)
|
||||||
{
|
{
|
||||||
if (p->val < 0xA)
|
if (p->val < 0xA)
|
||||||
log("%lu", p->val);
|
trace("%lu", p->val);
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sym = find_sym_by_addr(p->val);
|
sym = find_sym_by_addr(p->val);
|
||||||
|
|
||||||
if (sym)
|
if (sym)
|
||||||
log("$%s(0x%lX)", sym->name, sym->addr);
|
trace("$%s(0x%lX)", sym->name, sym->addr);
|
||||||
else
|
else
|
||||||
log("0x%lX", p->val);
|
trace("0x%lX", p->val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log("%c[", getmempref(p->mlen));
|
trace("%c[", getmempref(p->mlen));
|
||||||
|
|
||||||
mfmt = p->type & AM_MFMT_MASK;
|
mfmt = p->type & AM_MFMT_MASK;
|
||||||
|
|
||||||
if (mfmt == AM_IMM64)
|
if (mfmt == AM_IMM64)
|
||||||
log("0x%lX]", p->addr);
|
trace("0x%lX]", p->addr);
|
||||||
|
|
||||||
else if (mfmt == AM_RR)
|
else if (mfmt == AM_RR)
|
||||||
{
|
{
|
||||||
if (p->reg1 && p->reg2)
|
if (p->reg1 && p->reg2)
|
||||||
log("%s+%s]", ctx->r[p->reg1].name, ctx->r[p->reg2].name);
|
trace("%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 trace("%s]", ctx->r[p->reg1 ? p->reg1 : p->reg2].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (mfmt == AM_RRI)
|
else if (mfmt == AM_RRI)
|
||||||
{
|
{
|
||||||
if (p->reg1 && p->reg2)
|
if (p->reg1 && p->reg2)
|
||||||
log("%s+%s+%hd]", ctx->r[p->reg1].name,
|
trace("%s+%s+%hd]", ctx->r[p->reg1].name,
|
||||||
ctx->r[p->reg2].name, p->imm2);
|
ctx->r[p->reg2].name, p->imm2);
|
||||||
|
|
||||||
else log("%s+%hd]",
|
else trace("%s+%hd]",
|
||||||
ctx->r[p->reg1 ? p->reg1 : p->reg2].name, p->imm2);
|
ctx->r[p->reg1 ? p->reg1 : p->reg2].name, p->imm2);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (mfmt == AM_RRII)
|
else if (mfmt == AM_RRII)
|
||||||
{
|
{
|
||||||
if (p->reg1)
|
if (p->reg1)
|
||||||
log("%s+%s*%u+%hd]",
|
trace("%s+%s*%u+%hd]",
|
||||||
ctx->r[p->reg1].name,
|
ctx->r[p->reg1].name,
|
||||||
ctx->r[p->reg2].name,
|
ctx->r[p->reg2].name,
|
||||||
p->imm1, p->imm2);
|
p->imm1, p->imm2);
|
||||||
else
|
else
|
||||||
log("%s*%u+%hd]",
|
trace("%s*%u+%hd]",
|
||||||
ctx->r[p->reg2].name,
|
ctx->r[p->reg2].name,
|
||||||
p->imm1, p->imm2);
|
p->imm1, p->imm2);
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,13 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
|
|||||||
|
|
||||||
ulong orig_frame;
|
ulong orig_frame;
|
||||||
|
|
||||||
log("\nException %u - ", code);
|
logerr("\nException %u - ", code);
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vlog(fmt, ap);
|
vlog(fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
log("\n\n");
|
logerr("\n\n");
|
||||||
|
|
||||||
//
|
//
|
||||||
// Interrupted earlier?
|
// Interrupted earlier?
|
||||||
@ -27,7 +27,7 @@ void _except(ctx_t *ctx, int _code, char *fmt, ...)
|
|||||||
|
|
||||||
if (dying)
|
if (dying)
|
||||||
{
|
{
|
||||||
log("Exception thrown while dying=1\n");
|
logerr("Exception thrown while dying=1\n");
|
||||||
enable_stdin_echoing();
|
enable_stdin_echoing();
|
||||||
exit(-12);
|
exit(-12);
|
||||||
}
|
}
|
||||||
@ -94,23 +94,9 @@ actually_die:
|
|||||||
|
|
||||||
dying = 1;
|
dying = 1;
|
||||||
|
|
||||||
enable_stdin_echoing();
|
|
||||||
|
|
||||||
dumpregs(ctx);
|
dumpregs(ctx);
|
||||||
log("\n");
|
trace("\n");
|
||||||
|
|
||||||
if (ctx->mp)
|
die(code);
|
||||||
free(ctx->mp);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Shut down devices
|
|
||||||
//
|
|
||||||
if (devfiniall(ctx) < 0)
|
|
||||||
{
|
|
||||||
log("Couldn't deinitialize devices\n");
|
|
||||||
exit(-100 - code);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
vm/pc/log.c
11
vm/pc/log.c
@ -3,7 +3,16 @@
|
|||||||
|
|
||||||
#include <pc/arch.h>
|
#include <pc/arch.h>
|
||||||
|
|
||||||
void log(const char *fmt, ...)
|
void trace(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logerr(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
31
vm/pc/main.c
31
vm/pc/main.c
@ -2,9 +2,10 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include <pc/dev.h>
|
#include <pc/dev.h>
|
||||||
|
#include <cn/console.h>
|
||||||
|
|
||||||
#define FWPROGSIZE (1024 * 1024 * 1024)
|
#define FWPROGSIZE (1024 * 1024 * 1024)
|
||||||
static ssize_t fwsize;
|
static ssize_t fwsize;
|
||||||
@ -33,16 +34,7 @@ ctx_t main_ctx;
|
|||||||
|
|
||||||
void sigcommon(void)
|
void sigcommon(void)
|
||||||
{
|
{
|
||||||
dying = 1;
|
die(-13);
|
||||||
|
|
||||||
enable_stdin_echoing();
|
|
||||||
|
|
||||||
//
|
|
||||||
// Shut down devices
|
|
||||||
//
|
|
||||||
devfiniall(&main_ctx);
|
|
||||||
|
|
||||||
exit(-13);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sigint(int _)
|
void sigint(int _)
|
||||||
@ -52,7 +44,7 @@ void sigint(int _)
|
|||||||
|
|
||||||
void sigsegv(int _)
|
void sigsegv(int _)
|
||||||
{
|
{
|
||||||
log("Segmentation fault\n");
|
logerr("Segmentation fault\n");
|
||||||
sigcommon();
|
sigcommon();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +86,7 @@ int main(int argc, char **argv)
|
|||||||
// Load program
|
// Load program
|
||||||
//
|
//
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
log("Not enough arguments\n");
|
logerr("Not enough arguments\n");
|
||||||
exit(-3);
|
exit(-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,21 +95,21 @@ int main(int argc, char **argv)
|
|||||||
fwfile = fopen(argv[1], "rb");
|
fwfile = fopen(argv[1], "rb");
|
||||||
|
|
||||||
if (!fwfile) {
|
if (!fwfile) {
|
||||||
log("Couldn't open program file\n");
|
logerr("Couldn't open program file\n");
|
||||||
exit(-2);
|
exit(-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
fwprog = malloc(FWPROGSIZE);
|
fwprog = malloc(FWPROGSIZE);
|
||||||
|
|
||||||
if (!fwprog) {
|
if (!fwprog) {
|
||||||
log("Couldn't allocate firmware buffer\n");
|
logerr("Couldn't allocate firmware buffer\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fwsize = fread(fwprog, 1, FWPROGSIZE, fwfile);
|
fwsize = fread(fwprog, 1, FWPROGSIZE, fwfile);
|
||||||
|
|
||||||
if (fwsize < 2) {
|
if (fwsize < 2) {
|
||||||
log("Program file too small or empty\n");
|
logerr("Program file too small or empty\n");
|
||||||
free(fwprog);
|
free(fwprog);
|
||||||
exit(-3);
|
exit(-3);
|
||||||
}
|
}
|
||||||
@ -140,7 +132,7 @@ int main(int argc, char **argv)
|
|||||||
main_ctx.rf[RIP] = MEMOFF;
|
main_ctx.rf[RIP] = MEMOFF;
|
||||||
|
|
||||||
if (main_ctx.mp == 0) {
|
if (main_ctx.mp == 0) {
|
||||||
log("Couldn't allocate RAM\n");
|
logerr("Couldn't allocate RAM\n");
|
||||||
free(main_ctx.rf);
|
free(main_ctx.rf);
|
||||||
free(fwprog);
|
free(fwprog);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@ -153,12 +145,15 @@ int main(int argc, char **argv)
|
|||||||
//
|
//
|
||||||
main_ctx.dh = 0;
|
main_ctx.dh = 0;
|
||||||
if (devinitall(&main_ctx) < 0) {
|
if (devinitall(&main_ctx) < 0) {
|
||||||
log("Couldn't initialize devices\n");
|
logerr("Couldn't initialize devices\n");
|
||||||
free(main_ctx.rf);
|
free(main_ctx.rf);
|
||||||
free(fwprog);
|
free(fwprog);
|
||||||
exit(-10);
|
exit(-10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// To be moved to some screen device
|
||||||
|
console_init(&main_ctx);
|
||||||
|
|
||||||
disable_stdin_echoing();
|
disable_stdin_echoing();
|
||||||
main_loop();
|
main_loop();
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ ulong readmem(ctx_t *ctx, ulong addr, uint len)
|
|||||||
case 8:
|
case 8:
|
||||||
return readmem64(ctx, real, addr);
|
return readmem64(ctx, real, addr);
|
||||||
|
|
||||||
default: log("readmem() bad length %d!\n", len); abort();
|
default: logerr("readmem() bad length %d!\n", len); abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
@ -152,7 +152,7 @@ void writemem(ctx_t *ctx, ulong val, ulong addr, uint len)
|
|||||||
case 2: writemem16(ctx, val, real, addr); break;
|
case 2: writemem16(ctx, val, real, addr); break;
|
||||||
case 4: writemem32(ctx, val, real, addr); break;
|
case 4: writemem32(ctx, val, real, addr); break;
|
||||||
case 8: writemem64(ctx, val, real, addr); break;
|
case 8: writemem64(ctx, val, real, addr); break;
|
||||||
default: log("writemem() bad length %d!\n", len); abort();
|
default: logerr("writemem() bad length %d!\n", len); abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ ulong readmemzx(ctx_t *ctx, ulong addr, uint len)
|
|||||||
case 4: return readmem32(ctx, real, addr); break;
|
case 4: return readmem32(ctx, real, addr); break;
|
||||||
case 8: return readmem64(ctx, real, addr); break;
|
case 8: return readmem64(ctx, real, addr); break;
|
||||||
|
|
||||||
default: log("readmem() bad length %d!\n", len); abort();
|
default: logerr("readmemzx() bad length %d!\n", len); abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ void writememzx(ctx_t *ctx, ulong val, ulong addr, uint len)
|
|||||||
case 2: writemem16(ctx, val, real, addr); break;
|
case 2: writemem16(ctx, val, real, addr); break;
|
||||||
case 4: writemem32(ctx, val, real, addr); break;
|
case 4: writemem32(ctx, val, real, addr); break;
|
||||||
case 8: writemem64(ctx, val, real, addr); break;
|
case 8: writemem64(ctx, val, real, addr); break;
|
||||||
default: log("writemem() bad length %d!\n", len); abort();
|
default: logerr("writememzx() bad length %d!\n", len); abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
vm/pc/regs.c
28
vm/pc/regs.c
@ -74,9 +74,9 @@ reg_t arch_r[] =
|
|||||||
#define DUMPREGS(down, up) \
|
#define DUMPREGS(down, up) \
|
||||||
for (i = down; i <= up; i++) { \
|
for (i = down; i <= up; i++) { \
|
||||||
if (i % 4 == 0) \
|
if (i % 4 == 0) \
|
||||||
log("\n"); \
|
trace("\n"); \
|
||||||
r = &ctx->r[i]; \
|
r = &ctx->r[i]; \
|
||||||
log("%s=0x%-16lX ", r->name, R(i)); \
|
trace("%s=0x%-16lX ", r->name, R(i)); \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
extern size_t rfs_current_idx;
|
extern size_t rfs_current_idx;
|
||||||
@ -86,30 +86,30 @@ void dumpregs(ctx_t *ctx)
|
|||||||
int i;
|
int i;
|
||||||
reg_t *r;
|
reg_t *r;
|
||||||
|
|
||||||
log("Current RFRAME index: #%u\n", rfs_current_idx);
|
trace("Current RFRAME index: #%u\n", rfs_current_idx);
|
||||||
|
|
||||||
DUMPREGS(RAX, RDI);
|
DUMPREGS(RAX, RDI);
|
||||||
DUMPREGS(AX0, AX3);
|
DUMPREGS(AX0, AX3);
|
||||||
DUMPREGS(LX0, LX3);
|
DUMPREGS(LX0, LX3);
|
||||||
|
|
||||||
log("\n");
|
trace("\n");
|
||||||
DUMPREGS(NX0, NX3);
|
DUMPREGS(NX0, NX3);
|
||||||
DUMPREGS(SA0, SA3);
|
DUMPREGS(SA0, SA3);
|
||||||
DUMPREGS(CR0, CR3);
|
DUMPREGS(CR0, CR3);
|
||||||
DUMPREGS(CR4, CR7);
|
DUMPREGS(CR4, CR7);
|
||||||
|
|
||||||
|
|
||||||
log("\n\nrip=0x%-16lX rsp=0x%-16lX rbp=0x%-16lX rx0=%-16lu\n\n",
|
trace("\n\nrip=0x%-16lX rsp=0x%-16lX rbp=0x%-16lX rx0=%-16lu\n\n",
|
||||||
rip, rsp, rbp, ctx->ninstrs);
|
rip, rsp, rbp, ctx->ninstrs);
|
||||||
|
|
||||||
log("CF=%x OF=%x\n"
|
trace("CF=%x OF=%x\n"
|
||||||
"ZF=%x SF=%x\n"
|
"ZF=%x SF=%x\n"
|
||||||
"PF=%x DF=%x\n"
|
"PF=%x DF=%x\n"
|
||||||
"IF=%x UF=%x\n",
|
"IF=%x UF=%x\n",
|
||||||
!!(flg&CF), !!(flg&OF),
|
!!(flg&CF), !!(flg&OF),
|
||||||
!!(flg&ZF), !!(flg&SF),
|
!!(flg&ZF), !!(flg&SF),
|
||||||
!!(flg&PF), !!(flg&DF),
|
!!(flg&PF), !!(flg&DF),
|
||||||
!!(cr0&IF), !!(cr0&UF));
|
!!(cr0&IF), !!(cr0&UF));
|
||||||
|
|
||||||
assert(inv == 0);
|
assert(inv == 0);
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,8 @@ enum
|
|||||||
// CR0 register
|
// CR0 register
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
UF = 1 << 15, // User-mode flag
|
IF = 1 << 0, // Interrupts-enable flag
|
||||||
IF = 1 << 16, // Interrupts enable flag
|
UF = 1 << 1, // User-mode flag
|
||||||
};
|
};
|
||||||
|
|
||||||
struct reg_t
|
struct reg_t
|
||||||
|
@ -14,7 +14,7 @@ int create_symtab(const char *name)
|
|||||||
|
|
||||||
if (!tab)
|
if (!tab)
|
||||||
{
|
{
|
||||||
log("Couldn't open symtab\n");
|
logerr("Couldn't open symtab\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,9 +24,9 @@ int create_symtab(const char *name)
|
|||||||
|
|
||||||
if (prev_addr >= addr)
|
if (prev_addr >= addr)
|
||||||
{
|
{
|
||||||
log("Symbol addresses in symbol table not in increasing order\n");
|
logerr("Symbol addresses in symbol table not in increasing order\n");
|
||||||
log("Previous symbol: '%s' '%lu'\n", symtab[it-1].name, prev_addr);
|
logerr("Previous symbol: '%s' '%lu'\n", symtab[it-1].name, prev_addr);
|
||||||
log("Current symbol: '%s' '%lu'\n", buf, addr);
|
logerr("Current symbol: '%s' '%lu'\n", buf, addr);
|
||||||
exit(-55);
|
exit(-55);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user