Mercurial > pub > dyncall > dyncall
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 */ } } }