* if a subroutine has an lsda record, the actions have to cover all code

* cleanup

git-svn-id: branches/debug_eh@41453 -
This commit is contained in:
florian 2019-02-24 20:04:43 +00:00
parent db6916453d
commit 82e1ce8e4a
4 changed files with 114 additions and 28 deletions

View File

@ -731,6 +731,8 @@ implementation
exitlabel: tasmlabel; exitlabel: tasmlabel;
begin begin
current_asmdata.getjumplabel(exitlabel); current_asmdata.getjumplabel(exitlabel);
{ add an catch all action clause, at least psabieh needs this }
catch_all_add(list);
end_try_block(list,tek_except,t,entrystate,exitlabel); end_try_block(list,tek_except,t,entrystate,exitlabel);
emit_except_label(current_asmdata.CurrAsmList,tek_except,entrystate,t); emit_except_label(current_asmdata.CurrAsmList,tek_except,entrystate,t);
{ don't generate line info for internal cleanup } { don't generate line info for internal cleanup }
@ -1424,11 +1426,13 @@ implementation
location_reset(location,LOC_VOID,OS_NO); location_reset(location,LOC_VOID,OS_NO);
CurrentLandingPad:=nil; CurrentLandingPad:=nil;
CurrentAction:=nil;
ReRaiseLandingPad:=nil;
psabiehprocinfo:=current_procinfo as tpsabiehprocinfo; psabiehprocinfo:=current_procinfo as tpsabiehprocinfo;
{ a reraise must raise the exception to the parent exception frame } { a reraise must raise the exception to the parent exception frame }
if fc_catching_exceptions in flowcontrol then if fc_catching_exceptions in flowcontrol then
begin begin
psabiehprocinfo.CreateNewPSABIEHCallsite; psabiehprocinfo.CreateNewPSABIEHCallsite(current_asmdata.CurrAsmList);
CurrentLandingPad:=psabiehprocinfo.CurrentLandingPad; CurrentLandingPad:=psabiehprocinfo.CurrentLandingPad;
if psabiehprocinfo.PopLandingPad(CurrentLandingPad) then if psabiehprocinfo.PopLandingPad(CurrentLandingPad) then
exclude(flowcontrol,fc_catching_exceptions); exclude(flowcontrol,fc_catching_exceptions);
@ -1445,7 +1449,7 @@ implementation
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_reraise',[],nil).resetiftemp; hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_reraise',[],nil).resetiftemp;
if assigned(CurrentLandingPad) then if assigned(CurrentLandingPad) then
begin begin
psabiehprocinfo.CreateNewPSABIEHCallsite; psabiehprocinfo.CreateNewPSABIEHCallsite(current_asmdata.CurrAsmList);
if not(fc_catching_exceptions in flowcontrol) then if not(fc_catching_exceptions in flowcontrol) then
begin begin
psabiehprocinfo.PopLandingPad(psabiehprocinfo.CurrentLandingPad); psabiehprocinfo.PopLandingPad(psabiehprocinfo.CurrentLandingPad);

View File

@ -726,6 +726,9 @@ implementation
{ generate call frame marker for dwarf call frame info } { generate call frame marker for dwarf call frame info }
current_asmdata.asmcfi.start_frame(list); current_asmdata.asmcfi.start_frame(list);
{ labels etc. for exception frames are inserted here }
current_procinfo.start_eh(list);
if current_procinfo.procdef.proctypeoption=potype_proginit then if current_procinfo.procdef.proctypeoption=potype_proginit then
current_asmdata.asmcfi.outmost_frame(list); current_asmdata.asmcfi.outmost_frame(list);
@ -786,6 +789,9 @@ implementation
{ generate target specific proc exit code } { generate target specific proc exit code }
hlcg.g_proc_exit(list,parasize,(po_nostackframe in current_procinfo.procdef.procoptions)); hlcg.g_proc_exit(list,parasize,(po_nostackframe in current_procinfo.procdef.procoptions));
{ labels etc. for exception frames are inserted here }
current_procinfo.end_eh(list);
{ release return registers, needed for optimizer } { release return registers, needed for optimizer }
if not is_void(current_procinfo.procdef.returndef) then if not is_void(current_procinfo.procdef.returndef) then
paramanager.freecgpara(list,current_procinfo.procdef.funcretloc[calleeside]); paramanager.freecgpara(list,current_procinfo.procdef.funcretloc[calleeside]);

View File

@ -184,6 +184,10 @@ unit procinfo;
procedure setup_eh; virtual; procedure setup_eh; virtual;
procedure finish_eh; virtual; procedure finish_eh; virtual;
{ called to insert needed eh info into the entry code }
procedure start_eh(list : TAsmList); virtual;
{ called to insert needed eh info into the exit code }
procedure end_eh(list : TAsmList); virtual;
end; end;
tcprocinfo = class of tprocinfo; tcprocinfo = class of tprocinfo;
@ -349,4 +353,16 @@ implementation
{ no action by default } { no action by default }
end; end;
procedure tprocinfo.start_eh(list: TAsmList);
begin
{ no action by default }
end;
procedure tprocinfo.end_eh(list: TAsmList);
begin
{ no action by default }
end;
end. end.

View File

@ -34,7 +34,7 @@ unit psabiehpi;
globtype, globtype,
{ symtable } { symtable }
symconst,symtype,symdef,symsym, symconst,symtype,symdef,symsym,
node, node,nutils,
{ aasm } { aasm }
cpubase,cgbase,cgutils, cpubase,cgbase,cgutils,
aasmbase,aasmdata,aasmtai, aasmbase,aasmdata,aasmtai,
@ -55,13 +55,22 @@ unit psabiehpi;
compiled. compiled.
} }
tpsabiehprocinfo = class(tcgprocinfo) tpsabiehprocinfo = class(tcgprocinfo)
{ psabieh stuff, might be subject to be moved elsewhere } { set if the procedure needs exception tables because it
{ gcc exception table list that belongs to this routine } has exception generating nodes }
CreateExceptionTable: Boolean;
{ if a procedure needs exception tables, this is the outmost landing pad
with "no action", covering everything not covered by other landing pads
since a procedure which has one landing pad need to be covered completely by landing pads }
OutmostLandingPad: TPSABIEHAction;
callsite_table_data, callsite_table_data,
action_table_data, action_table_data,
gcc_except_table_data : TAsmList; gcc_except_table_data : TAsmList;
typefilterlistlabel,typefilterlistlabelref, typefilterlistlabel,typefilterlistlabelref,
callsitetablestart,callsitetableend : TAsmLabel; callsitetablestart,callsitetableend,
{ first label which must be inserted into the entry code }
entrycallsitestart,
callsitelaststart : TAsmLabel; callsitelaststart : TAsmLabel;
typefilterlist, typefilterlist,
landingpadstack, landingpadstack,
@ -81,7 +90,7 @@ unit psabiehpi;
procedure PushLandingPad(action: TPSABIEHAction); procedure PushLandingPad(action: TPSABIEHAction);
function CurrentLandingPad: TPSABIEHAction;inline; function CurrentLandingPad: TPSABIEHAction;inline;
function PopLandingPad(action: TPSABIEHAction): boolean; function PopLandingPad(action: TPSABIEHAction): boolean;
procedure CreateNewPSABIEHCallsite; procedure CreateNewPSABIEHCallsite(list: TAsmList);
{ adds a new type to the type filter list and returns its index { adds a new type to the type filter list and returns its index
be aware, that this method can also handle catch all filters so it be aware, that this method can also handle catch all filters so it
is valid to pass nil } is valid to pass nil }
@ -89,6 +98,10 @@ unit psabiehpi;
procedure set_eh_info; override; procedure set_eh_info; override;
procedure setup_eh; override; procedure setup_eh; override;
procedure finish_eh; override; procedure finish_eh; override;
procedure start_eh(list : TAsmList); override;
procedure end_eh(list : TAsmList); override;
function find_exception_handling(var n: tnode; para: pointer): foreachnoderesult; virtual;
end; end;
implementation implementation
@ -226,8 +239,10 @@ implementation
include(flags,pi_has_except_table_data); include(flags,pi_has_except_table_data);
if CurrentAction<>action then if CurrentAction<>action then
internalerror(2019021006); internalerror(2019021006);
{ no further actions follow, finalize table } { no further actions follow, finalize table
if landingpadstack.count>0 then we check for >1 as the outmost landing pad has no action, so
we can ignore it }
if landingpadstack.count>1 then
begin begin
current_asmdata.getlabel(curpos,alt_data); current_asmdata.getlabel(curpos,alt_data);
action.actionlist.concat(tai_label.create(curpos)); action.actionlist.concat(tai_label.create(curpos));
@ -262,7 +277,7 @@ implementation
end; end;
procedure tpsabiehprocinfo.CreateNewPSABIEHCallsite; procedure tpsabiehprocinfo.CreateNewPSABIEHCallsite(list : TAsmList);
var var
callsiteend : TAsmLabel; callsiteend : TAsmLabel;
begin begin
@ -278,7 +293,7 @@ implementation
{$endif debug_eh} {$endif debug_eh}
callsite_table_data.concat(tai_const.create_rel_sym(aitconst_uleb128bit,TDwarfAsmCFI(current_asmdata.AsmCFI).get_frame_start,callsitelaststart)); callsite_table_data.concat(tai_const.create_rel_sym(aitconst_uleb128bit,TDwarfAsmCFI(current_asmdata.AsmCFI).get_frame_start,callsitelaststart));
current_asmdata.getlabel(callsiteend,alt_eh_end); current_asmdata.getlabel(callsiteend,alt_eh_end);
current_asmdata.CurrAsmList.concat(tai_label.create(callsiteend)); list.concat(tai_label.create(callsiteend));
callsite_table_data.concat(tai_const.create_rel_sym(aitconst_uleb128bit,callsitelaststart,callsiteend)); callsite_table_data.concat(tai_const.create_rel_sym(aitconst_uleb128bit,callsitelaststart,callsiteend));
{ landing pad? } { landing pad? }
if assigned(CurrentLandingPad.landingpad) then if assigned(CurrentLandingPad.landingpad) then
@ -290,19 +305,25 @@ implementation
begin begin
callsite_table_data.concat(tai_const.Create_rel_sym_offset(aitconst_uleb128bit,callsitetableend,CurrentLandingPad.actiontablelabel,1)); callsite_table_data.concat(tai_const.Create_rel_sym_offset(aitconst_uleb128bit,callsitetableend,CurrentLandingPad.actiontablelabel,1));
{$ifdef debug_eh} {$ifdef debug_eh}
current_asmdata.CurrAsmList.concat(tai_comment.Create(strpnew('New call site '+tostr(CurrentCallSiteNumber)+', action table index = '+tostr(landingpadstack.count-1)))); list.concat(tai_comment.Create(strpnew('New call site '+tostr(CurrentCallSiteNumber)+', action table index = '+tostr(landingpadstack.count-1))));
{$endif debug_eh} {$endif debug_eh}
end end
else else
begin begin
callsite_table_data.concat(tai_const.Create_uleb128bit(0)); callsite_table_data.concat(tai_const.Create_uleb128bit(0));
{$ifdef debug_eh} {$ifdef debug_eh}
current_asmdata.CurrAsmList.concat(tai_comment.Create(strpnew('New call site '+tostr(CurrentCallSiteNumber)+', no action'))); list.concat(tai_comment.Create(strpnew('New call site '+tostr(CurrentCallSiteNumber)+', no action')));
{$endif debug_eh} {$endif debug_eh}
end
end; end;
current_asmdata.getlabel(callsitelaststart,alt_eh_begin); current_asmdata.getlabel(callsitelaststart,alt_eh_begin);
current_asmdata.CurrAsmList.concat(tai_label.create(callsitelaststart)); list.concat(tai_label.create(callsitelaststart));
end
else
begin
current_asmdata.getlabel(entrycallsitestart,alt_eh_begin);
callsitelaststart:=entrycallsitestart
end;
Inc(CurrentCallSiteNumber); Inc(CurrentCallSiteNumber);
end; end;
@ -337,10 +358,21 @@ implementation
end; end;
function tpsabiehprocinfo.find_exception_handling(var n: tnode; para: pointer): foreachnoderesult;
begin
if n.nodetype in [tryfinallyn,tryexceptn,raisen,onn] then
Result:=fen_norecurse_true
else
Result:=fen_false;
end;
procedure tpsabiehprocinfo.setup_eh; procedure tpsabiehprocinfo.setup_eh;
var var
gcc_except_table: tai_section; gcc_except_table: tai_section;
begin begin
CreateExceptionTable:=foreachnode(code,@find_exception_handling,nil);
gcc_except_table_data:=TAsmList.Create; gcc_except_table_data:=TAsmList.Create;
callsite_table_data:=TAsmList.Create; callsite_table_data:=TAsmList.Create;
action_table_data:=TAsmList.Create; action_table_data:=TAsmList.Create;
@ -362,6 +394,16 @@ implementation
callsite_table_data.concat(tai_label.create(callsitetablestart)); callsite_table_data.concat(tai_label.create(callsitetablestart));
cexceptionstatehandler:=tpsabiehexceptionstatehandler; cexceptionstatehandler:=tpsabiehexceptionstatehandler;
if CreateExceptionTable then
begin
CreateNewPSABIEHCallsite(current_asmdata.CurrAsmList);
OutmostLandingPad:=TPSABIEHAction.Create(nil);
PushAction(OutmostLandingPad);
PushLandingPad(OutmostLandingPad);
OutmostLandingPad.AddAction(nil);
end;
end; end;
@ -430,6 +472,26 @@ implementation
end; end;
procedure tpsabiehprocinfo.start_eh(list: TAsmList);
begin
inherited start_eh(list);
if CreateExceptionTable then
list.insert(tai_label.create(entrycallsitestart));
end;
procedure tpsabiehprocinfo.end_eh(list: TAsmList);
begin
inherited end_eh(list);
if CreateExceptionTable then
begin
CreateNewPSABIEHCallsite(list);
PopLandingPad(CurrentLandingPad);
PopAction(OutmostLandingPad);
end;
end;
class procedure tpsabiehexceptionstatehandler.get_exception_temps(list: TAsmList; var t: texceptiontemps); class procedure tpsabiehexceptionstatehandler.get_exception_temps(list: TAsmList; var t: texceptiontemps);
begin begin
tg.gethltemp(list,ossinttype,ossinttype.size,tt_persistent,t.reasonbuf); tg.gethltemp(list,ossinttype,ossinttype.size,tt_persistent,t.reasonbuf);
@ -461,7 +523,7 @@ implementation
exceptstate.finallycodelabel:=nil; exceptstate.finallycodelabel:=nil;
action:=TPSABIEHAction.Create(exceptstate.exceptionlabel); action:=TPSABIEHAction.Create(exceptstate.exceptionlabel);
end; end;
(current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite; (current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite(list);
(current_procinfo as tpsabiehprocinfo).PushAction(action); (current_procinfo as tpsabiehprocinfo).PushAction(action);
(current_procinfo as tpsabiehprocinfo).PushLandingPad(action); (current_procinfo as tpsabiehprocinfo).PushLandingPad(action);
if exceptframekind<>tek_except then if exceptframekind<>tek_except then
@ -505,8 +567,6 @@ implementation
var var
reg: TRegister; reg: TRegister;
begin begin
(current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite;
(current_procinfo as tpsabiehprocinfo).PopLandingPad((current_procinfo as tpsabiehprocinfo).CurrentLandingPad);
if exceptframekind<>tek_except then if exceptframekind<>tek_except then
begin begin
{ record that no exception happened in the reason buf, in case we are in a try block of a finally statement } { record that no exception happened in the reason buf, in case we are in a try block of a finally statement }
@ -517,14 +577,15 @@ implementation
inherited; inherited;
if exceptframekind=tek_except then if exceptframekind=tek_except then
hlcg.a_jmp_always(list,endlabel); hlcg.a_jmp_always(list,endlabel);
(current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite(list);
(current_procinfo as tpsabiehprocinfo).PopLandingPad((current_procinfo as tpsabiehprocinfo).CurrentLandingPad);
end; end;
class procedure tpsabiehexceptionstatehandler.free_exception(list: TAsmList; const t: texceptiontemps; const s: texceptionstate; a: aint; class procedure tpsabiehexceptionstatehandler.free_exception(list: TAsmList; const t: texceptiontemps; const s: texceptionstate; a: aint;
endexceptlabel: tasmlabel; onlyfree: boolean); endexceptlabel: tasmlabel; onlyfree: boolean);
begin begin
(current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite; (current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite(list);
// inherited free_exception(list, t, s, a, endexceptlabel, onlyfree);
end; end;
@ -542,11 +603,12 @@ implementation
{ Resume might not be called outside of an landing pad else { Resume might not be called outside of an landing pad else
the unwind is immediatly terminated, so create an empty landing pad } the unwind is immediatly terminated, so create an empty landing pad }
psabiehprocinfo:=current_procinfo as tpsabiehprocinfo; psabiehprocinfo:=current_procinfo as tpsabiehprocinfo;
psabiehprocinfo.CreateNewPSABIEHCallsite; psabiehprocinfo.CreateNewPSABIEHCallsite(list);
ReRaiseLandingPad:=TPSABIEHAction.Create(nil); ReRaiseLandingPad:=TPSABIEHAction.Create(nil);
psabiehprocinfo.PushAction(ReRaiseLandingPad); psabiehprocinfo.PushAction(ReRaiseLandingPad);
psabiehprocinfo.PushLandingPad(ReRaiseLandingPad); psabiehprocinfo.PushLandingPad(ReRaiseLandingPad);
ReRaiseLandingPad.AddAction(nil);
pd:=search_system_proc('fpc_resume'); pd:=search_system_proc('fpc_resume');
cgpara1.init; cgpara1.init;
@ -556,7 +618,7 @@ implementation
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_resume',[@cgpara1],nil).resetiftemp; hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_resume',[@cgpara1],nil).resetiftemp;
cgpara1.done; cgpara1.done;
psabiehprocinfo.CreateNewPSABIEHCallsite; psabiehprocinfo.CreateNewPSABIEHCallsite(list);
psabiehprocinfo.PopLandingPad(psabiehprocinfo.CurrentLandingPad); psabiehprocinfo.PopLandingPad(psabiehprocinfo.CurrentLandingPad);
psabiehprocinfo.PopAction(ReRaiseLandingPad); psabiehprocinfo.PopAction(ReRaiseLandingPad);
end end
@ -566,7 +628,7 @@ implementation
{ empty landing pad needed to avoid immediate termination? } { empty landing pad needed to avoid immediate termination? }
if psabiehprocinfo.landingpadstack.Count=0 then if psabiehprocinfo.landingpadstack.Count=0 then
begin begin
psabiehprocinfo.CreateNewPSABIEHCallsite; psabiehprocinfo.CreateNewPSABIEHCallsite(list);
ReRaiseLandingPad:=TPSABIEHAction.Create(nil); ReRaiseLandingPad:=TPSABIEHAction.Create(nil);
psabiehprocinfo.PushAction(ReRaiseLandingPad); psabiehprocinfo.PushAction(ReRaiseLandingPad);
@ -577,7 +639,7 @@ implementation
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_reraise',[],nil).resetiftemp; hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_reraise',[],nil).resetiftemp;
if assigned(ReRaiseLandingPad) then if assigned(ReRaiseLandingPad) then
begin begin
psabiehprocinfo.CreateNewPSABIEHCallsite; psabiehprocinfo.CreateNewPSABIEHCallsite(list);
psabiehprocinfo.PopLandingPad(psabiehprocinfo.CurrentLandingPad); psabiehprocinfo.PopLandingPad(psabiehprocinfo.CurrentLandingPad);
psabiehprocinfo.PopAction(ReRaiseLandingPad); psabiehprocinfo.PopAction(ReRaiseLandingPad);
end; end;
@ -701,9 +763,7 @@ implementation
class procedure tpsabiehexceptionstatehandler.cleanupobjectstack(list: TAsmList); class procedure tpsabiehexceptionstatehandler.cleanupobjectstack(list: TAsmList);
begin begin
// inherited cleanupobjectstack(list); { there is nothing to do }
//!!! some catch all clause needed?
//!!! internalerror(2019021004)
end; end;