* 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;
begin
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);
emit_except_label(current_asmdata.CurrAsmList,tek_except,entrystate,t);
{ don't generate line info for internal cleanup }
@ -1424,11 +1426,13 @@ implementation
location_reset(location,LOC_VOID,OS_NO);
CurrentLandingPad:=nil;
CurrentAction:=nil;
ReRaiseLandingPad:=nil;
psabiehprocinfo:=current_procinfo as tpsabiehprocinfo;
{ a reraise must raise the exception to the parent exception frame }
if fc_catching_exceptions in flowcontrol then
begin
psabiehprocinfo.CreateNewPSABIEHCallsite;
psabiehprocinfo.CreateNewPSABIEHCallsite(current_asmdata.CurrAsmList);
CurrentLandingPad:=psabiehprocinfo.CurrentLandingPad;
if psabiehprocinfo.PopLandingPad(CurrentLandingPad) then
exclude(flowcontrol,fc_catching_exceptions);
@ -1445,7 +1449,7 @@ implementation
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_reraise',[],nil).resetiftemp;
if assigned(CurrentLandingPad) then
begin
psabiehprocinfo.CreateNewPSABIEHCallsite;
psabiehprocinfo.CreateNewPSABIEHCallsite(current_asmdata.CurrAsmList);
if not(fc_catching_exceptions in flowcontrol) then
begin
psabiehprocinfo.PopLandingPad(psabiehprocinfo.CurrentLandingPad);

View File

@ -726,6 +726,9 @@ implementation
{ generate call frame marker for dwarf call frame info }
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
current_asmdata.asmcfi.outmost_frame(list);
@ -786,6 +789,9 @@ implementation
{ generate target specific proc exit code }
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 }
if not is_void(current_procinfo.procdef.returndef) then
paramanager.freecgpara(list,current_procinfo.procdef.funcretloc[calleeside]);

View File

@ -184,6 +184,10 @@ unit procinfo;
procedure setup_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;
tcprocinfo = class of tprocinfo;
@ -349,4 +353,16 @@ implementation
{ no action by default }
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.

View File

@ -34,7 +34,7 @@ unit psabiehpi;
globtype,
{ symtable }
symconst,symtype,symdef,symsym,
node,
node,nutils,
{ aasm }
cpubase,cgbase,cgutils,
aasmbase,aasmdata,aasmtai,
@ -55,13 +55,22 @@ unit psabiehpi;
compiled.
}
tpsabiehprocinfo = class(tcgprocinfo)
{ psabieh stuff, might be subject to be moved elsewhere }
{ gcc exception table list that belongs to this routine }
{ set if the procedure needs exception tables because it
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,
action_table_data,
gcc_except_table_data : TAsmList;
typefilterlistlabel,typefilterlistlabelref,
callsitetablestart,callsitetableend : TAsmLabel;
callsitetablestart,callsitetableend,
{ first label which must be inserted into the entry code }
entrycallsitestart,
callsitelaststart : TAsmLabel;
typefilterlist,
landingpadstack,
@ -81,7 +90,7 @@ unit psabiehpi;
procedure PushLandingPad(action: TPSABIEHAction);
function CurrentLandingPad: TPSABIEHAction;inline;
function PopLandingPad(action: TPSABIEHAction): boolean;
procedure CreateNewPSABIEHCallsite;
procedure CreateNewPSABIEHCallsite(list: TAsmList);
{ 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
is valid to pass nil }
@ -89,6 +98,10 @@ unit psabiehpi;
procedure set_eh_info; override;
procedure setup_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;
implementation
@ -226,8 +239,10 @@ implementation
include(flags,pi_has_except_table_data);
if CurrentAction<>action then
internalerror(2019021006);
{ no further actions follow, finalize table }
if landingpadstack.count>0 then
{ no further actions follow, finalize table
we check for >1 as the outmost landing pad has no action, so
we can ignore it }
if landingpadstack.count>1 then
begin
current_asmdata.getlabel(curpos,alt_data);
action.actionlist.concat(tai_label.create(curpos));
@ -262,7 +277,7 @@ implementation
end;
procedure tpsabiehprocinfo.CreateNewPSABIEHCallsite;
procedure tpsabiehprocinfo.CreateNewPSABIEHCallsite(list : TAsmList);
var
callsiteend : TAsmLabel;
begin
@ -278,7 +293,7 @@ implementation
{$endif debug_eh}
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.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));
{ landing pad? }
if assigned(CurrentLandingPad.landingpad) then
@ -290,19 +305,25 @@ implementation
begin
callsite_table_data.concat(tai_const.Create_rel_sym_offset(aitconst_uleb128bit,callsitetableend,CurrentLandingPad.actiontablelabel,1));
{$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}
end
else
begin
callsite_table_data.concat(tai_const.Create_uleb128bit(0));
{$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}
end
end;
current_asmdata.getlabel(callsitelaststart,alt_eh_begin);
list.concat(tai_label.create(callsitelaststart));
end
else
begin
current_asmdata.getlabel(entrycallsitestart,alt_eh_begin);
callsitelaststart:=entrycallsitestart
end;
current_asmdata.getlabel(callsitelaststart,alt_eh_begin);
current_asmdata.CurrAsmList.concat(tai_label.create(callsitelaststart));
Inc(CurrentCallSiteNumber);
end;
@ -337,10 +358,21 @@ implementation
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;
var
gcc_except_table: tai_section;
begin
CreateExceptionTable:=foreachnode(code,@find_exception_handling,nil);
gcc_except_table_data:=TAsmList.Create;
callsite_table_data:=TAsmList.Create;
action_table_data:=TAsmList.Create;
@ -362,6 +394,16 @@ implementation
callsite_table_data.concat(tai_label.create(callsitetablestart));
cexceptionstatehandler:=tpsabiehexceptionstatehandler;
if CreateExceptionTable then
begin
CreateNewPSABIEHCallsite(current_asmdata.CurrAsmList);
OutmostLandingPad:=TPSABIEHAction.Create(nil);
PushAction(OutmostLandingPad);
PushLandingPad(OutmostLandingPad);
OutmostLandingPad.AddAction(nil);
end;
end;
@ -430,6 +472,26 @@ implementation
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);
begin
tg.gethltemp(list,ossinttype,ossinttype.size,tt_persistent,t.reasonbuf);
@ -461,7 +523,7 @@ implementation
exceptstate.finallycodelabel:=nil;
action:=TPSABIEHAction.Create(exceptstate.exceptionlabel);
end;
(current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite;
(current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite(list);
(current_procinfo as tpsabiehprocinfo).PushAction(action);
(current_procinfo as tpsabiehprocinfo).PushLandingPad(action);
if exceptframekind<>tek_except then
@ -505,8 +567,6 @@ implementation
var
reg: TRegister;
begin
(current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite;
(current_procinfo as tpsabiehprocinfo).PopLandingPad((current_procinfo as tpsabiehprocinfo).CurrentLandingPad);
if exceptframekind<>tek_except then
begin
{ 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;
if exceptframekind=tek_except then
hlcg.a_jmp_always(list,endlabel);
(current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite(list);
(current_procinfo as tpsabiehprocinfo).PopLandingPad((current_procinfo as tpsabiehprocinfo).CurrentLandingPad);
end;
class procedure tpsabiehexceptionstatehandler.free_exception(list: TAsmList; const t: texceptiontemps; const s: texceptionstate; a: aint;
endexceptlabel: tasmlabel; onlyfree: boolean);
begin
(current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite;
// inherited free_exception(list, t, s, a, endexceptlabel, onlyfree);
(current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite(list);
end;
@ -542,11 +603,12 @@ implementation
{ Resume might not be called outside of an landing pad else
the unwind is immediatly terminated, so create an empty landing pad }
psabiehprocinfo:=current_procinfo as tpsabiehprocinfo;
psabiehprocinfo.CreateNewPSABIEHCallsite;
psabiehprocinfo.CreateNewPSABIEHCallsite(list);
ReRaiseLandingPad:=TPSABIEHAction.Create(nil);
psabiehprocinfo.PushAction(ReRaiseLandingPad);
psabiehprocinfo.PushLandingPad(ReRaiseLandingPad);
ReRaiseLandingPad.AddAction(nil);
pd:=search_system_proc('fpc_resume');
cgpara1.init;
@ -556,7 +618,7 @@ implementation
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_resume',[@cgpara1],nil).resetiftemp;
cgpara1.done;
psabiehprocinfo.CreateNewPSABIEHCallsite;
psabiehprocinfo.CreateNewPSABIEHCallsite(list);
psabiehprocinfo.PopLandingPad(psabiehprocinfo.CurrentLandingPad);
psabiehprocinfo.PopAction(ReRaiseLandingPad);
end
@ -566,7 +628,7 @@ implementation
{ empty landing pad needed to avoid immediate termination? }
if psabiehprocinfo.landingpadstack.Count=0 then
begin
psabiehprocinfo.CreateNewPSABIEHCallsite;
psabiehprocinfo.CreateNewPSABIEHCallsite(list);
ReRaiseLandingPad:=TPSABIEHAction.Create(nil);
psabiehprocinfo.PushAction(ReRaiseLandingPad);
@ -577,7 +639,7 @@ implementation
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_reraise',[],nil).resetiftemp;
if assigned(ReRaiseLandingPad) then
begin
psabiehprocinfo.CreateNewPSABIEHCallsite;
psabiehprocinfo.CreateNewPSABIEHCallsite(list);
psabiehprocinfo.PopLandingPad(psabiehprocinfo.CurrentLandingPad);
psabiehprocinfo.PopAction(ReRaiseLandingPad);
end;
@ -701,9 +763,7 @@ implementation
class procedure tpsabiehexceptionstatehandler.cleanupobjectstack(list: TAsmList);
begin
// inherited cleanupobjectstack(list);
//!!! some catch all clause needed?
//!!! internalerror(2019021004)
{ there is nothing to do }
end;