comparison dyncall/dyncall_aggregate_x64.c @ 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 ba70fb631bea
children
comparison
equal deleted inserted replaced
550:5e1002095afa 551:eef302b7a58d
68 /* field outside of qword at index? */ 68 /* field outside of qword at index? */
69 if(offset >= (qword_offset + DC_ONE_8BYTE) || (offset + f->size * f->array_len) <= qword_offset) 69 if(offset >= (qword_offset + DC_ONE_8BYTE) || (offset + f->size * f->array_len) <= qword_offset)
70 continue; 70 continue;
71 71
72 /* if field is unaligned, class is MEMORY */ 72 /* if field is unaligned, class is MEMORY */
73 if(f->alignment && (offset % f->alignment) != 0) 73 assert((f->alignment & (f->alignment - 1)) == 0); /* f->alignment required to be a power of 2*/
74 if(f->alignment && (offset & (f->alignment - 1)) != 0) /* offset not a multiple of (power of 2) f->alignment? */
74 return SYSVC_MEMORY; 75 return SYSVC_MEMORY;
75 76
76 DCuchar new_class = SYSVC_NONE; 77 DCuchar new_class = SYSVC_NONE;
77 78
78 switch (f->type) { 79 switch (f->type) {
94 case DC_SIGCHAR_FLOAT: 95 case DC_SIGCHAR_FLOAT:
95 case DC_SIGCHAR_DOUBLE: 96 case DC_SIGCHAR_DOUBLE:
96 new_class = SYSVC_SSE; 97 new_class = SYSVC_SSE;
97 break; 98 break;
98 case DC_SIGCHAR_AGGREGATE: 99 case DC_SIGCHAR_AGGREGATE:
99 /* skip empty structs */ 100 /* skip empty structs */
100 if(f->size) 101 if(f->size)
101 { 102 {
102 /* aggregate arrays need to be checked per element, as an aggregate can be composed of 103 /* aggregate arrays need to be checked per element, as an aggregate can be composed of
103 * multiple types, potentially split across an 8byte; loop only over parts within 8byte */ 104 * multiple types, potentially split across an 8byte; loop only over parts within 8byte */
104 int j = (qword_offset-offset) / f->size; 105 int j = (qword_offset-offset) / f->size;
105 int k = DC_ONE_8BYTE / f->size + j + 1; /* +1 for split array elements at end of 8byte */ 106 int k = DC_ONE_8BYTE / f->size + j + 1; /* +1 for split array elements at end of 8byte */
106 if(k > f->array_len) 107 if(k > f->array_len)
107 k = f->array_len; 108 k = f->array_len;
108 109
109 for(; j<k; ++j) { 110 for(; j<k; ++j)
110 //@@@STRUCT new_class = dc_get_sysv_class_for_8byte(f->sub_aggr, index, offset + f->size*j);
111 //@@@STRUCT clz = dc_merge_sysv_classes(clz, new_class);
112 new_class = dc_merge_sysv_classes(new_class, dc_get_sysv_class_for_8byte(f->sub_aggr, index, offset + f->size*j)); 111 new_class = dc_merge_sysv_classes(new_class, dc_get_sysv_class_for_8byte(f->sub_aggr, index, offset + f->size*j));
113 }
114 } 112 }
115 break; 113 break;
116 /*case DClongdouble, DCcomplexfloat DCcomplexdouble DCcomplexlongdouble etc... -> x87/x87up/complexx87 classes @@@AGGR implement */ 114 /*case DClongdouble, DCcomplexfloat DCcomplexdouble DCcomplexlongdouble etc... -> x87/x87up/complexx87 classes @@@AGGR implement */
117 } 115 }
118 116