Browse Source

+ emit_push_mem_size() which pushes a value in memory of a certain size
* pushsetelement() and pushvaluepara() use this new procedure, because
otherwise they could sometimes try to push data past the end of the
heap, causing a crash
(merged from fixes branch)

Jonas Maebe 25 years ago
parent
commit
ede6479557
1 changed files with 46 additions and 7 deletions
  1. 46 7
      compiler/cgai386.pas

+ 46 - 7
compiler/cgai386.pas

@@ -77,6 +77,7 @@ unit cgai386;
     procedure emit_lea_loc_ref(const t:tlocation;const ref:treference;freetemp:boolean);
     procedure emit_lea_loc_ref(const t:tlocation;const ref:treference;freetemp:boolean);
     procedure emit_lea_loc_reg(const t:tlocation;reg:tregister;freetemp:boolean);
     procedure emit_lea_loc_reg(const t:tlocation;reg:tregister;freetemp:boolean);
     procedure emit_push_loc(const t:tlocation);
     procedure emit_push_loc(const t:tlocation);
+    procedure emit_push_mem_size(const t: treference; size: longint);
 
 
     { pushes qword location to the stack }
     { pushes qword location to the stack }
     procedure emit_pushq_loc(const t : tlocation);
     procedure emit_pushq_loc(const t : tlocation);
@@ -842,6 +843,38 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
         end;
         end;
       end;
       end;
 
 
+    procedure emit_push_mem_size(const t: treference; size: longint);
+      
+      var
+        s: topsize;
+      
+      begin
+        if t.is_immediate then
+           push_int(t.offset)
+        else
+          if size < 4 then
+            begin
+              getexplicitregister32(R_EDI);
+              case size of
+                1: s := S_BL;
+                2: s := S_WL;
+                else internalerror(200008071);
+              end;
+              exprasmlist^.concat(new(paicpu,op_ref_reg(A_MOVZX,s,
+                newreference(t),R_EDI)));
+              if target_os.stackalignment=4 then
+                exprasmlist^.concat(new(paicpu,op_reg(A_PUSH,S_L,R_EDI)))
+              else
+                exprasmlist^.concat(new(paicpu,op_reg(A_PUSH,S_W,R_DI)));
+              ungetregister32(R_EDI);
+            end
+          else
+            if size = 4 then
+              emit_push_mem(t)
+            else
+              internalerror(200008072);
+      end;
+
 
 
     procedure emit_to_mem(var p:ptree);
     procedure emit_to_mem(var p:ptree);
 
 
@@ -1356,10 +1389,10 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
                end;
                end;
            else
            else
              begin
              begin
-               if target_os.stackalignment=4 then
-                 exprasmlist^.concat(new(paicpu,op_ref(A_PUSH,S_L,newreference(p^.location.reference))))
-               else
-                 exprasmlist^.concat(new(paicpu,op_ref(A_PUSH,S_W,newreference(p^.location.reference))));
+               { you can't push more bytes than the size of the element, }
+               { because this may cross a page boundary and you'll get a }
+               { sigsegv (JM)                                            }
+               emit_push_mem_size(p^.location.reference,1);
                del_reference(p^.location.reference);
                del_reference(p^.location.reference);
              end;
              end;
            end;
            end;
@@ -1682,8 +1715,7 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
 {$endif noAllocEdi}
 {$endif noAllocEdi}
                                 end
                                 end
                                else
                                else
-                                exprasmlist^.concat(new(paicpu,op_ref(A_PUSH,opsize,
-                                  newreference(tempreference))));
+                                emit_push_mem_size(tempreference,p^.resulttype^.size);
                              end;
                              end;
                            else
                            else
                              internalerror(234231);
                              internalerror(234231);
@@ -4029,7 +4061,14 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.7  2000-08-03 13:17:25  jonas
+  Revision 1.8  2000-08-07 11:29:40  jonas
+    + emit_push_mem_size() which pushes a value in memory of a certain size
+    * pushsetelement() and pushvaluepara() use this new procedure, because
+      otherwise they could sometimes try to push data past the end of the
+      heap, causing a crash
+     (merged from fixes branch)
+
+  Revision 1.7  2000/08/03 13:17:25  jonas
     + allow regvars to be used inside inlined procs, which required  the
     + allow regvars to be used inside inlined procs, which required  the
       following changes:
       following changes:
         + load regvars in genentrycode/free them in genexitcode (cgai386)
         + load regvars in genentrycode/free them in genexitcode (cgai386)