sim: handle exit_group() syscall, exit with simulated program's exit status

This commit is contained in:
Mikael Pettersson 2020-07-08 13:44:14 +02:00
parent dcfc247527
commit b44534221f
3 changed files with 18 additions and 8 deletions

View File

@ -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.

View File

@ -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,

View File

@ -41,12 +41,16 @@
%% are from Linux' <asm-generic/errno.h>.
-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),