changeset 551:eef302b7a58d

- amendment fix for buffer overflow (see commit 0455834d29a1), to also handle non-standard struct packing, + better asserts - changelog wording tweaks for clarity - comment tweaks for clarity - (mostly pointless) microoptimization in aggr alignment calculation, avoiding a modulo, as alignment always a power of 2 - cleanups
author Tassilo Philipp
date Mon, 20 Jun 2022 14:57:49 +0200
parents 5e1002095afa
children 61c485f8cc06
files ChangeLog dyncall/dyncall_aggregate.c dyncall/dyncall_aggregate_x64.c dyncallback/dyncall_args_x64.c
diffstat 4 files changed, 25 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Jun 20 14:24:37 2022 +0200
+++ b/ChangeLog	Mon Jun 20 14:57:49 2022 +0200
@@ -4,8 +4,9 @@
 Version 1.4 (upcoming)
 
 dyncall:
+  o new, portable aggregate-by-value argument interface
   o aggregate-by-value (struct, union) support for x64 (win and sysv; thanks Raphael Luba!)
-  o new aggregate arg interface DCaggr replacing stale DCstruct (latter had shortcomings, was
+  o new aggregate description interface DCaggr replacing stale DCstruct (latter had shortcomings, was
     mostly unused as it lacked stable implementations, didn't handle unions, ...)
   o new calling convention modes for thiscalls (platform agnostic DC_CALL_C_DEFAULT_THIS, as well as
     DC_CALL_C_X64_{WIN64,SYSV}_THIS (needed to handle C++ ABI rules for returning aggregates by value)
@@ -16,11 +17,9 @@
   o windows/x64/masm directives added to specify how stack unwinds (help for
     debuggers, exception handling, etc.; thanks Raphael Luba)
 dyncallback:
-  o stack unwinding debug help on windows (thanks Raphael Luba!)
+  o new, portable aggregate-by-value callback argument interface
   o aggregate-by-value (struct, union) support for x64 (win and sysv; thanks Raphael Luba!)
-  o new aggregate arg interface DCaggr
-  o windows/x64/masm directives added to specify how stack unwinds (help for
-    debuggers, exception handling, etc.; thanks Raphael Luba)
+  o x64/windows masm directives for frame unwinding information (as dbg help; thanks Raphael Luba!)
 dynload:
   o build fix for ReactOS with RosBE/cmake/mingw-make environment
 tests:
--- a/dyncall/dyncall_aggregate.c	Mon Jun 20 14:24:37 2022 +0200
+++ b/dyncall/dyncall_aggregate.c	Mon Jun 20 14:57:49 2022 +0200
@@ -84,7 +84,7 @@
 			va_end(ap);
 
 			f->size = f->sub_aggr->size;
-			f->alignment = f->sub_aggr->alignment;
+			f->alignment = f->sub_aggr->alignment; /* field inherit's sub aggrs alignment*/
 			break;
 		}
 		default:
@@ -94,7 +94,7 @@
 	if(type != DC_SIGCHAR_AGGREGATE)
 		f->alignment = f->size;
 
-	/* aggr's field alignment is relative largest field size */
+	/* aggr's field alignment is relative to largest field size */
 	if(ag->alignment < f->alignment)
 		ag->alignment = f->alignment;
 }
--- a/dyncall/dyncall_aggregate_x64.c	Mon Jun 20 14:24:37 2022 +0200
+++ b/dyncall/dyncall_aggregate_x64.c	Mon Jun 20 14:57:49 2022 +0200
@@ -70,7 +70,8 @@
       continue;
 
     /* if field is unaligned, class is MEMORY */
-    if(f->alignment && (offset % f->alignment) != 0)
+    assert((f->alignment & (f->alignment - 1)) == 0);      /* f->alignment required to be a power of 2*/
+    if(f->alignment && (offset & (f->alignment - 1)) != 0) /* offset not a multiple of (power of 2) f->alignment? */
       return SYSVC_MEMORY;
 
     DCuchar new_class = SYSVC_NONE;
@@ -96,8 +97,8 @@
         new_class = SYSVC_SSE;
         break;
       case DC_SIGCHAR_AGGREGATE:
-	    /* skip empty structs */
-	    if(f->size)
+        /* skip empty structs */
+        if(f->size)
         {
           /* aggregate arrays need to be checked per element, as an aggregate can be composed of
            * multiple types, potentially split across an 8byte; loop only over parts within 8byte */
@@ -106,11 +107,8 @@
           if(k > f->array_len)
             k = f->array_len;
 
-          for(; j<k; ++j) {
-            //@@@STRUCT new_class = dc_get_sysv_class_for_8byte(f->sub_aggr, index, offset + f->size*j);
-            //@@@STRUCT clz = dc_merge_sysv_classes(clz, new_class);
+          for(; j<k; ++j)
             new_class = dc_merge_sysv_classes(new_class, dc_get_sysv_class_for_8byte(f->sub_aggr, index, offset + f->size*j));
-          }
         }
         break;
       /*case DClongdouble, DCcomplexfloat DCcomplexdouble DCcomplexlongdouble etc... -> x87/x87up/complexx87 classes @@@AGGR implement */
--- a/dyncallback/dyncall_args_x64.c	Mon Jun 20 14:24:37 2022 +0200
+++ b/dyncallback/dyncall_args_x64.c	Mon Jun 20 14:57:49 2022 +0200
@@ -106,26 +106,30 @@
   {
     for(i=0; ag->sysv_classes[i] && i<DC_SYSV_MAX_NUM_CLASSES; ++i)
     {
+      size_t s = ag->size - i*8;
+      s = s<8?s:8;
+
       switch (ag->sysv_classes[i])
       {
         case SYSVC_INTEGER:
-          switch (ag->size - i*8) {
-            case 1:  *(DCchar *)(((DClonglong*)target) + i) = dcbArgChar    (p); break;
-            case 2:  *(DCshort*)(((DClonglong*)target) + i) = dcbArgShort   (p); break;
-            case 4:  *(DCint  *)(((DClonglong*)target) + i) = dcbArgInt     (p); break;
-            default: *          (((DClonglong*)target) + i) = dcbArgLongLong(p); break;
+          {
+            DClonglong l = dcbArgLongLong(p);
+            memcpy((DClonglong*)target + i, &l, s);
           }
           break;
 
         case SYSVC_SSE:
-          switch (ag->size - i*8) {
-            case 4:  *(DCfloat*)(((DCdouble*)target) + i) = dcbArgFloat (p); break;
-            default: *          (((DCdouble*)target) + i) = dcbArgDouble(p); break;
-          }
+          if(s == 8)
+            *(((DCdouble*)target) + i) = dcbArgDouble(p);
+          else if(s == 4)
+            *(DCfloat*)(((DCdouble*)target) + i) = dcbArgFloat (p);
+          else
+            assert(DC_FALSE && "SYSV aggregate floating point slot mismatch (unexpected size of fp field)");
           break;
+
         /* @@@AGGR implement when implementing x87 types */
         default:
-            assert(DC_FALSE && "Should never be reached because we check for unupported classes earlier");
+            assert(DC_FALSE && "unsupported SYSV aggregate slot classification"); /* shouldn't be reached, as we check for unupported classes earlier */
       }
     }
   }