Mercurial > pub > dyncall > dyncall
changeset 549:0455834d29a1
- dyncallback: x64/sysv buffer overflow fix for aggregate args whose size isn't a multiple of 8
author | Tassilo Philipp |
---|---|
date | Mon, 20 Jun 2022 11:15:09 +0200 |
parents | a6d00ee46731 |
children | 5e1002095afa |
files | dyncallback/dyncall_args_x64.c |
diffstat | 1 files changed, 16 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/dyncallback/dyncall_args_x64.c Mon Jun 20 11:04:20 2022 +0200 +++ b/dyncallback/dyncall_args_x64.c Mon Jun 20 11:15:09 2022 +0200 @@ -100,7 +100,7 @@ if(ag->sysv_classes[0] == SYSVC_MEMORY || (n_regs.i > numIntRegs) || (n_regs.f > numFloatRegs)) { memcpy(target, p->stack_ptr, ag->size); - p->stack_ptr = p->stack_ptr + ((ag->size + (sizeof(DClonglong)-1)) >> 3); // advance to next full stack slot + p->stack_ptr = p->stack_ptr + ((ag->size + (sizeof(DClonglong)-1)) >> 3); /* advance to next full stack slot */ } else { @@ -108,8 +108,21 @@ { switch (ag->sysv_classes[i]) { - case SYSVC_INTEGER: ((DClonglong*)target)[i] = dcbArgLongLong(p); break; - case SYSVC_SSE: ((DCdouble *)target)[i] = dcbArgDouble (p); break; + 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; + } + 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; + } + break; /* @@@AGGR implement when implementing x87 types */ default: assert(DC_FALSE && "Should never be reached because we check for unupported classes earlier");