comparison dyncallback/dyncall_args_x64.c @ 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 111236b31c75
children eef302b7a58d
comparison
equal deleted inserted replaced
548:a6d00ee46731 549:0455834d29a1
98 } 98 }
99 99
100 if(ag->sysv_classes[0] == SYSVC_MEMORY || (n_regs.i > numIntRegs) || (n_regs.f > numFloatRegs)) 100 if(ag->sysv_classes[0] == SYSVC_MEMORY || (n_regs.i > numIntRegs) || (n_regs.f > numFloatRegs))
101 { 101 {
102 memcpy(target, p->stack_ptr, ag->size); 102 memcpy(target, p->stack_ptr, ag->size);
103 p->stack_ptr = p->stack_ptr + ((ag->size + (sizeof(DClonglong)-1)) >> 3); // advance to next full stack slot 103 p->stack_ptr = p->stack_ptr + ((ag->size + (sizeof(DClonglong)-1)) >> 3); /* advance to next full stack slot */
104 } 104 }
105 else 105 else
106 { 106 {
107 for(i=0; ag->sysv_classes[i] && i<DC_SYSV_MAX_NUM_CLASSES; ++i) 107 for(i=0; ag->sysv_classes[i] && i<DC_SYSV_MAX_NUM_CLASSES; ++i)
108 { 108 {
109 switch (ag->sysv_classes[i]) 109 switch (ag->sysv_classes[i])
110 { 110 {
111 case SYSVC_INTEGER: ((DClonglong*)target)[i] = dcbArgLongLong(p); break; 111 case SYSVC_INTEGER:
112 case SYSVC_SSE: ((DCdouble *)target)[i] = dcbArgDouble (p); break; 112 switch (ag->size - i*8) {
113 case 1: *(DCchar *)(((DClonglong*)target) + i) = dcbArgChar (p); break;
114 case 2: *(DCshort*)(((DClonglong*)target) + i) = dcbArgShort (p); break;
115 case 4: *(DCint *)(((DClonglong*)target) + i) = dcbArgInt (p); break;
116 default: * (((DClonglong*)target) + i) = dcbArgLongLong(p); break;
117 }
118 break;
119
120 case SYSVC_SSE:
121 switch (ag->size - i*8) {
122 case 4: *(DCfloat*)(((DCdouble*)target) + i) = dcbArgFloat (p); break;
123 default: * (((DCdouble*)target) + i) = dcbArgDouble(p); break;
124 }
125 break;
113 /* @@@AGGR implement when implementing x87 types */ 126 /* @@@AGGR implement when implementing x87 types */
114 default: 127 default:
115 assert(DC_FALSE && "Should never be reached because we check for unupported classes earlier"); 128 assert(DC_FALSE && "Should never be reached because we check for unupported classes earlier");
116 } 129 }
117 } 130 }