261 lines
5.6 KiB
C
261 lines
5.6 KiB
C
/* ###
|
|
* IP: GHIDRA
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#include "pcode_test.h"
|
|
#include "big_struct.h"
|
|
|
|
static i4 int_expectedValue;
|
|
static i4 int_actualValue;
|
|
|
|
static i4 breakPointHere(void)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
i4 recursionTestLevel(i4 level, u1 * array, i4 len)
|
|
{
|
|
i4 i, ret = 0;
|
|
u1 localArray[128];
|
|
|
|
for (i = 0; i < sizeof(localArray); i++) {
|
|
localArray[i] = (8 * level) + i;
|
|
}
|
|
|
|
if (level < 4 && (ret = recursionTestLevel(level + 1, localArray, len))) {
|
|
return 1;
|
|
}
|
|
/* verify array integrity */
|
|
for (i = 0; i < sizeof(localArray); i++) {
|
|
if (localArray[i] != ((8 * level) + i)) {
|
|
return ret + 1;
|
|
}
|
|
}
|
|
/* verify array integrity */
|
|
for (i = 0; i < sizeof(localArray); i++) {
|
|
if (array[i] != ((8 * (level - 1)) + i)) {
|
|
return ret + 1;
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
i2 nalign_i2(i2 in)
|
|
{
|
|
char buffer[128];
|
|
|
|
*(i2 *) (buffer + 1) = in;
|
|
in += *(i2 *) (buffer + 1);
|
|
*(i2 *) (buffer + 2) = in;
|
|
in += *(i2 *) (buffer + 2);
|
|
*(i2 *) (buffer + 3) = in;
|
|
in += *(i2 *) (buffer + 3);
|
|
*(i2 *) (buffer + 4) = in;
|
|
in += *(i2 *) (buffer + 4);
|
|
return in;
|
|
}
|
|
|
|
i4 nalign_i4(i4 in)
|
|
{
|
|
char buffer[128];
|
|
|
|
*(i4 *) (buffer + 1) = in;
|
|
in += *(i4 *) (buffer + 1);
|
|
*(i4 *) (buffer + 2) = in;
|
|
in += *(i4 *) (buffer + 2);
|
|
*(i4 *) (buffer + 3) = in;
|
|
in += *(i4 *) (buffer + 3);
|
|
*(i4 *) (buffer + 4) = in;
|
|
in += *(i4 *) (buffer + 4);
|
|
return in;
|
|
}
|
|
|
|
#ifdef HAS_LONGLONG
|
|
i8 nalign_i8(i8 in)
|
|
{
|
|
char buffer[128];
|
|
*(i8 *) (buffer + 1) = in;
|
|
in += *(i8 *) (buffer + 1);
|
|
*(i8 *) (buffer + 2) = in;
|
|
in += *(i8 *) (buffer + 2);
|
|
*(i8 *) (buffer + 3) = in;
|
|
in += *(i8 *) (buffer + 3);
|
|
*(i8 *) (buffer + 4) = in;
|
|
in += *(i8 *) (buffer + 4);
|
|
return in;
|
|
}
|
|
#endif /* #ifdef HAS_LONGLONG */
|
|
|
|
i4 nalign_struct(big_struct_type * in)
|
|
{
|
|
i4 ret = 0;
|
|
char buffer[128];
|
|
|
|
in->i = 0x5;
|
|
if (in->i != 0x5)
|
|
ret++;
|
|
in->s = 0x6;
|
|
if (in->s != 0x6)
|
|
ret++;
|
|
in->c = 0x7;
|
|
if (in->c != 0x7)
|
|
ret++;
|
|
#ifdef HAS_LONGLONG
|
|
in->ll = 0x8;
|
|
if (in->ll != 0x8)
|
|
ret++;
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
u4 pcode_memset(u1 *lhs, u1 val, u4 len)
|
|
{
|
|
memset(lhs, val, (size_t) len);
|
|
return *(u4 *) lhs;
|
|
}
|
|
|
|
void *pcode_memcpy(u1 * lhs, u1 * rhs, u4 len)
|
|
{
|
|
return memcpy(lhs, rhs, (size_t) len);
|
|
}
|
|
|
|
u4 pcode_memcmp_u4(u4 lhs, u4 rhs)
|
|
{
|
|
return (u4) (memcmp(&lhs, &rhs, 4) == 0 ? 0 : 1);
|
|
}
|
|
|
|
u4 pcode_memcmp_n(u1 * lhs, u1 * rhs, u4 len)
|
|
{
|
|
return (u4) (memcmp(lhs, rhs, (size_t) len) == 0 ? 0 : 1);
|
|
}
|
|
|
|
#if defined(HAS_FLOAT) && defined(HAS_DOUBLE) && defined(HAS_LONGLONG)
|
|
|
|
/* Almost equal here means a difference between f1 and f2 that is less
|
|
* than 1% of f2. Naturally, f2 != 0. Implement it without calling
|
|
* fabs, which would cast everything to double anyway.
|
|
*/
|
|
|
|
static int FLOAT_ALMOST_EQUAL(double f1, double f2)
|
|
{
|
|
double d = (f1 >= f2 ? f1 - f2 : f2 - f1);
|
|
double m = (f2 >= 0.0 ? f2 : -f2) * 0.01;
|
|
return d < m;
|
|
}
|
|
|
|
i4 pcode_conversions(int argc)
|
|
{
|
|
i1 u1buff[8];
|
|
u2 u2buff[8];
|
|
u4 u4buff[8];
|
|
u8 u8buff[8];
|
|
f4 f4buff[8];
|
|
f8 f8buff[8];
|
|
u8 ret = 0;
|
|
i4 i = 0;
|
|
|
|
f4 f4_1 = argc;
|
|
f4 f4_2 = 4.0 - f4_1;
|
|
if (f4_2 != 4.0)
|
|
return 101;
|
|
|
|
f4 f4_3 = f4_1 + 5.0;
|
|
if (f4_3 != 5.0)
|
|
return 102;
|
|
|
|
f8 f8_1 = argc;
|
|
f8 f8_2 = 4.0 - f8_1;
|
|
if (f8_2 != 4.0)
|
|
return 103;
|
|
|
|
f8 f8_3 = f8_1 + 5.0;
|
|
if (f8_3 != 5.0)
|
|
return 104;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
u1buff[i] = 0;
|
|
u2buff[i] = 0;
|
|
u4buff[i] = 0;
|
|
u8buff[i] = 0;
|
|
f4buff[i] = 0;
|
|
f8buff[i] = 0;
|
|
}
|
|
u8buff[0] = 0x0FFFFFFFFFFFFFFFULL;
|
|
|
|
u4buff[0] = u8buff[0] + argc;
|
|
|
|
u2buff[0] = u8buff[0] + argc;
|
|
u2buff[1] = u4buff[0] + argc;
|
|
|
|
u1buff[0] = u8buff[0] + argc;
|
|
u1buff[1] = u4buff[0] + argc;
|
|
u1buff[2] = u2buff[0] + argc;
|
|
|
|
if (u1buff[0] != (i1) 0xff || u1buff[1] != (i1) 0xff || u1buff[2] != (i1) 0xff || u2buff[0] != 0xffff || u2buff[1] != 0xffff || u4buff[0] != 0xffffffff || u8buff[0] != 0x0fffffffffffffffULL)
|
|
return 1;
|
|
|
|
f4buff[0] = 1.0 + argc;
|
|
if (!FLOAT_ALMOST_EQUAL(f4buff[0], 1.0))
|
|
return 21;
|
|
|
|
f4buff[0] = u8buff[0] + argc;
|
|
if (!FLOAT_ALMOST_EQUAL(f4buff[0], 1.152921504606846976e+18))
|
|
return 2;
|
|
|
|
f4buff[1] = u4buff[0] + argc;
|
|
if (!FLOAT_ALMOST_EQUAL(f4buff[1], 4.294967296e+09))
|
|
return 3;
|
|
|
|
f4buff[2] = u2buff[0] + argc;
|
|
if (!FLOAT_ALMOST_EQUAL(f4buff[2], 6.5535e+04))
|
|
return 4;
|
|
|
|
f4buff[3] = u1buff[0] + argc;
|
|
if (!FLOAT_ALMOST_EQUAL(f4buff[3], -1.0e+00))
|
|
return 5;
|
|
|
|
f8buff[0] = u8buff[0] + argc;
|
|
if (!FLOAT_ALMOST_EQUAL(f8buff[0], 1.152921504606846976e+18))
|
|
return 6;
|
|
|
|
f8buff[1] = u4buff[0] + argc;
|
|
if (!FLOAT_ALMOST_EQUAL(f8buff[1], 4.294967295e+09))
|
|
return 7;
|
|
f8buff[2] = u2buff[0] + argc;
|
|
if (!FLOAT_ALMOST_EQUAL(f8buff[2], 6.5535e+04))
|
|
return 8;
|
|
|
|
f8buff[3] = u1buff[0] + argc;
|
|
if (!FLOAT_ALMOST_EQUAL(f8buff[3], -1.0e+00))
|
|
return 9;
|
|
|
|
f8buff[4] = f4buff[0] + argc;
|
|
if (!FLOAT_ALMOST_EQUAL(f8buff[4], 1.152921504606846976e+18))
|
|
return 10;
|
|
|
|
f8 tmpf8 = f8buff[4] + f8buff[3] - f8buff[2] + f8buff[1] - f8buff[0]
|
|
+ f4buff[4] + f4buff[3] - f4buff[2] + f4buff[1] - f4buff[0];
|
|
|
|
if (!FLOAT_ALMOST_EQUAL(tmpf8, -1.15292149601704345600e+18))
|
|
return 11;
|
|
|
|
u8 retll = u1buff[0] + u1buff[1] - u1buff[2] + u4buff[0] + u8buff[0];
|
|
|
|
if (retll != 0x10000000fffffffdULL)
|
|
return 12;
|
|
|
|
return 0; // OK
|
|
}
|
|
#endif /* #if defined(HAS_FLOAT) && defined(HAS_DOUBLE) && defined(HAS_LONGLONG) */
|