Преглед на файлове

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

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

florian преди 6 години
родител
ревизия
82e1ce8e4a
променени са 4 файла, в които са добавени 114 реда и са изтрити 28 реда
  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;
       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);

+ 6 - 0
compiler/ncgutil.pas

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

+ 16 - 0
compiler/procinfo.pas

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

+ 86 - 26
compiler/psabiehpi.pas

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