ghidra/Ghidra/Extensions/SleighDevTools/pcodetest/c_src/misc_BODY.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) */