Browse Source

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

git-svn-id: branches/debug_eh@41453 -

florian 6 years ago
parent
commit
82e1ce8e4a
4 changed files with 114 additions and 28 deletions
  1. 6 2
      compiler/ncgflw.pas
  2. 6 0
      compiler/ncgutil.pas
  3. 16 0
      compiler/procinfo.pas
  4. 86 26
      compiler/psabiehpi.pas

+ 6 - 2
compiler/ncgflw.pas

@@ -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);

+ 6 - 0
compiler/ncgutil.pas

@@ -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]);

+ 16 - 0
compiler/procinfo.pas

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

+ 86 - 26
compiler/psabiehpi.pas

@@ -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 }
-         { 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,
          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 }
-        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
           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;
+            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;
           end;
-        current_asmdata.getlabel(callsitelaststart,alt_eh_begin);
-        current_asmdata.CurrAsmList.concat(tai_label.create(callsitelaststart));
+
         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;
-//        inherited free_exception(list, t, s, a, endexceptlabel, onlyfree);
+        (current_procinfo as tpsabiehprocinfo).CreateNewPSABIEHCallsite(list);
       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);
-//!!! some catch all clause needed?
-//!!!        internalerror(2019021004)
+        { there is nothing to do }
       end;
       end;