From b44534221fe11e7aaabd6e3f60361285e1fc8e40 Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Wed, 8 Jul 2020 13:44:14 +0200 Subject: [PATCH] sim: handle exit_group() syscall, exit with simulated program's exit status --- erlang/apps/sim/src/sim.erl | 5 ++++- erlang/apps/sim/src/sim_core.erl | 13 ++++++++----- erlang/apps/sim/src/sim_kernel.erl | 8 ++++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/erlang/apps/sim/src/sim.erl b/erlang/apps/sim/src/sim.erl index 68b9e6e..4bb07a3 100644 --- a/erlang/apps/sim/src/sim.erl +++ b/erlang/apps/sim/src/sim.erl @@ -147,7 +147,10 @@ version() -> do_sim(#options{exe = Exe, argv = Argv}) -> case sim_loader:load(Exe, Argv, simenv()) of {ok, {Mem, PC, SP, Argc, ArgvPtr, Envp}} -> - sim_core:run(Mem, PC, SP, Argc, ArgvPtr, Envp); + case sim_core:run(Mem, PC, SP, Argc, ArgvPtr, Envp) of + {ok, Status} -> halt(Status band 8#377); + {error, _Reason} = Error -> Error + end; {error, _Reason} = Error -> Error end. diff --git a/erlang/apps/sim/src/sim_core.erl b/erlang/apps/sim/src/sim_core.erl index 1e0b051..d7b7ba6 100644 --- a/erlang/apps/sim/src/sim_core.erl +++ b/erlang/apps/sim/src/sim_core.erl @@ -26,6 +26,7 @@ -export([ run/6 , next_pc/2 + , get_ac/2 , set_ac/3 , set_flag/2 , format_error/1 @@ -40,7 +41,7 @@ SP :: word(), Argc :: word(), Argv :: word(), - Envp :: word()) -> ok | {error, {module(), term()}}. + Envp :: word()) -> {ok, integer()} | {error, {module(), term()}}. run(Mem, PC, SP, Argc, Argv, Envp) -> PCSection = (PC bsr 18) band ((1 bsl 12) - 1), PCOffset = PC band ((1 bsl 18) - 1), @@ -63,12 +64,14 @@ run(Mem, PC, SP, Argc, Argv, Envp) -> %% faults (especially page faults) that may occur at various points, without %% creating recursion in the simulator. --spec run(#core{}, sim_mem:mem()) -> {#core{}, sim_mem:mem(), ok | {error, {module(), term()}}}. +-spec run(#core{}, sim_mem:mem()) + -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}. run(Core, Mem) -> insn_fetch(Core, Mem). %% Sequential control flow: increment PC but stay in current section. --spec next_pc(#core{}, sim_mem:mem()) -> {#core{}, sim_mem:mem(), ok | {error, {module(), term()}}}. +-spec next_pc(#core{}, sim_mem:mem()) + -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}. next_pc(#core{pc_offset = PCOffset} = Core, Mem) -> PCOffset1 = (PCOffset + 1) band ((1 bsl 18) - 1), insn_fetch(Core#core{pc_offset = PCOffset1}, Mem). @@ -212,7 +215,7 @@ global_indirect_word(Core, Mem, IR, MB, I) -> %% Instruction Dispatch ======================================================== -spec dispatch(#core{}, sim_mem:mem(), IR :: word(), #ea{}) - -> {#core{}, sim_mem:mem(), ok | {error, {module(), term()}}}. + -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}. dispatch(Core, Mem, IR, EA) -> %% Dispatch on the opcode (top 9 bits). case IR bsr 4 of @@ -230,7 +233,7 @@ handle_MOVEI(Core, Mem, IR, #ea{offset = E}) -> %% Page Fault Handling ========================================================= -spec page_fault(#core{}, sim_mem:mem(), word(), atom(), term(), fun()) - -> {#core{}, sim_mem:mem(), ok | {error, {module(), term()}}}. + -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}. page_fault(Core, Mem, Address, Op, Reason, Cont) -> %% This should trap to kernel mode, but for now we treat all faults as fatal. PC = (Core#core.pc_section bsl 18) bor Core#core.pc_offset, diff --git a/erlang/apps/sim/src/sim_kernel.erl b/erlang/apps/sim/src/sim_kernel.erl index 8f86a58..569a845 100644 --- a/erlang/apps/sim/src/sim_kernel.erl +++ b/erlang/apps/sim/src/sim_kernel.erl @@ -41,12 +41,16 @@ %% are from Linux' . -spec handle_JSYS(#core{}, sim_mem:mem(), IR :: word(), #ea{}) - -> {#core{}, sim_mem:mem(), ok | {error, {module(), term()}}}. -handle_JSYS(Core, Mem, _IR, #ea{offset = Nr} = _EA) -> + -> {#core{}, sim_mem:mem(), {ok, integer()} | {error, {module(), term()}}}. +handle_JSYS(Core, Mem, _IR, #ea{offset = Nr}) -> case Nr of + 94 -> handle_exit_group(Core, Mem); _ -> return_errno(Core, Mem, ?ENOSYS) end. +handle_exit_group(Core, Mem) -> + {Core, Mem, {ok, sim_core:get_ac(Core, 1)}}. + return_errno(Core0, Mem, Errno) -> Core1 = sim_core:set_ac(Core0, 1, Errno), Core2 = sim_core:set_flag(Core1, ?PDP10_PF_OVERFLOW),