Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:25
erlang
1881-beam_validator-Improve-stack-frame-validat...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 1881-beam_validator-Improve-stack-frame-validation.patch of Package erlang
From 468839f127dc9f41bff14fd921c9666cb270eb2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20H=C3=B6gberg?= <john@erlang.org> Date: Tue, 20 Dec 2022 15:38:05 +0100 Subject: [PATCH 1/2] beam_validator: Improve stack frame validation --- lib/compiler/src/beam_validator.erl | 43 +++++++++++++++++++--- lib/compiler/test/beam_validator_SUITE.erl | 8 ++-- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index b99bcd16ab..fe5b711edf 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -186,7 +186,7 @@ validate_0([{function, Name, Arity, Entry, Code} | Fs], Module, Level, Ft) -> %% %% Note that this may be 0 if there's a frame without saved values, %% such as on a body-recursive call. - numy=none :: none | undecided | index(), + numy=none :: none | {undecided,index()} | index(), %% Available heap size. h=0, %% Available heap size for funs (aka lambdas). @@ -2996,7 +2996,7 @@ merge_states_1(StA, StB, Counter0) -> RecvSt = merge_receive_state(RecvStA, RecvStB), MsPos = merge_ms_positions(MsPosA, MsPosB, Vs), Fragile = merge_fragility(FragA, FragB), - NumY = merge_stk(NumYA, NumYB), + NumY = merge_stk(YsA, YsB, NumYA, NumYB), Ct = merge_ct(CtA, CtB), St = #st{xs=Xs,ys=Ys,vs=Vs,fragile=Fragile,numy=NumY, @@ -3134,8 +3134,38 @@ merge_ms_positions_1([], _MsPosA, _MsPosB, _Vs, Acc) -> merge_receive_state(Same, Same) -> Same; merge_receive_state(_, _) -> undecided. -merge_stk(S, S) -> S; -merge_stk(_, _) -> undecided. +merge_stk(_, _, S, S) -> + S; +merge_stk(YsA, YsB, StkA, StkB) -> + merge_stk_undecided(YsA, YsB, StkA, StkB). + +merge_stk_undecided(YsA, YsB, {undecided, StkA}, {undecided, StkB}) -> + %% We're merging two branches with different stack sizes. This is only okay + %% if we're about to throw an exception, in which case all Y registers must + %% be initialized on both paths. + ok = merge_stk_verify_init(StkA - 1, YsA), + ok = merge_stk_verify_init(StkB - 1, YsB), + + {undecided, min(StkA, StkB)}; +merge_stk_undecided(YsA, YsB, StkA, StkB) when is_integer(StkA) -> + merge_stk_undecided(YsA, YsB, {undecided, StkA}, StkB); +merge_stk_undecided(YsA, YsB, StkA, StkB) when is_integer(StkB) -> + merge_stk_undecided(YsA, YsB, StkA, {undecided, StkB}); +merge_stk_undecided(YsA, YsB, none, StkB) -> + merge_stk_undecided(YsA, YsB, {undecided, 0}, StkB); +merge_stk_undecided(YsA, YsB, StkA, none) -> + merge_stk_undecided(YsA, YsB, StkA, {undecided, 0}). + +merge_stk_verify_init(-1, _Ys) -> + ok; +merge_stk_verify_init(Y, Ys) -> + Reg = {y, Y}, + case Ys of + #{ Reg := TagOrVRef } when TagOrVRef =/= uninitialized -> + merge_stk_verify_init(Y - 1, Ys); + #{} -> + error({unsafe_stack, Reg, Ys}) + end. merge_ct(S, S) -> S; merge_ct(Ct0, Ct1) -> merge_ct_1(Ct0, Ct1). @@ -3154,8 +3184,9 @@ verify_y_init(#vst{current=#st{numy=NumY,ys=Ys}}=Vst) when is_integer(NumY) -> true = NumY > HighestY, %Assertion. verify_y_init_1(NumY - 1, Vst), ok; -verify_y_init(#vst{current=#st{numy=undecided,ys=Ys}}=Vst) -> +verify_y_init(#vst{current=#st{numy={undecided,MinSlots},ys=Ys}}=Vst) -> HighestY = maps:fold(fun({y,Y}, _, Acc) -> max(Y, Acc) end, -1, Ys), + true = MinSlots > HighestY, %Assertion. verify_y_init_1(HighestY, Vst); verify_y_init(#vst{}) -> ok. @@ -3188,7 +3219,7 @@ verify_live_1(X, Vst) when is_integer(X) -> verify_no_ct(#vst{current=#st{numy=none}}) -> ok; -verify_no_ct(#vst{current=#st{numy=undecided}}) -> +verify_no_ct(#vst{current=#st{numy={undecided,_}}}) -> error(unknown_size_of_stackframe); verify_no_ct(#vst{current=St}=Vst) -> case collect_try_catch_tags(St#st.numy - 1, Vst, []) of diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index 8cbc5e9d7a..5a00a9ecf7 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -182,9 +182,11 @@ call_without_stack(Config) when is_list(Config) -> merge_undefined(Config) when is_list(Config) -> Errors = do_val(merge_undefined, Config), [{{t,undecided,2}, - {{call_ext,2,{extfunc,debug,filter,2}}, - 22, - {allocated,undecided}}}, + {{label,11}, + 19, + {unsafe_stack,{y,1}, + #{{y,0} := uninitialized, + {y,1} := uninitialized}}}}, {{t,uninitialized,2}, {{call_ext,2,{extfunc,io,format,2}}, 17, -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor