Skip to content

Instantly share code, notes, and snippets.

@gavv
Created June 13, 2019 11:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gavv/4a0fa01c401c480db2b24fa2f50e49db to your computer and use it in GitHub Desktop.
Save gavv/4a0fa01c401c480db2b24fa2f50e49db to your computer and use it in GitHub Desktop.
of_add_to_multiple_symbols
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
typedef uint64_t UINT64;
typedef uint32_t UINT32;
typedef uint8_t UINT8;
#define OF_ENTER_FUNCTION
#ifndef OF_DEBUG
void of_add_to_multiple_symbols (void **to,
const void *from,
UINT32 to_size,
UINT32 symbol_size)
#else
void of_add_to_multiple_symbols (void **to,
const void *from,
UINT32 to_size,
UINT32 symbol_size,
UINT32 *op)
#endif
{
OF_ENTER_FUNCTION
#ifdef OF_DEBUG
if (op != NULL)
(*op) += to_size;
#endif
UINT32 i;
//#ifndef ASSEMBLY_SSE_OPT /* { */
UINT32 symbolSize32;
UINT32 symbolSize32rem;
symbolSize32 = symbol_size >> 2;
symbolSize32rem = symbol_size % 4; // Remaining bytes when the symbol
// size is not multiple of 32 bits.
#if defined (__LP64__) || (__WORDSIZE == 64) // {
/*
* 64-bit machines
*/
UINT32 symbolSize64; // Size of symbols in 64-bit unit
// symbol_size is not necessarily a multiple of 8, but >> 3 will divide
// it by 8 and keep the integral part automatically.
symbolSize64 = symbol_size >> 3;
UINT64 *pt1, *pt2, *pt3, *pt4, *pt5, *pt6, *pt7, *pt8, *from_s, from_value;
while (to_size >= 8)
{
from_s = (UINT64*) from; // to pointer to 64-bit integers
pt1 = (UINT64*)to[0];
pt2 = (UINT64*)to[1];
pt3 = (UINT64*)to[2];
pt4 = (UINT64*)to[3];
pt5 = (UINT64*)to[4];
pt6 = (UINT64*)to[5];
pt7 = (UINT64*)to[6];
pt8 = (UINT64*)to[7];
to += 8;
to_size -= 8;
for (i = symbolSize64; i > 0; i--)
{
from_value = *from_s;
*pt1 ^= from_value;
*pt2 ^= from_value ;
*pt3 ^= from_value ;
*pt4 ^= from_value ;
*pt5 ^= from_value ;
*pt6 ^= from_value ;
*pt7 ^= from_value ;
*pt8 ^= from_value ;
from_s++;
pt1++;
pt2++;
pt3++;
pt4++;
pt5++;
pt6++;
pt7++;
pt8++;
}
UINT32* from_s32 = (UINT32*) from_s; // to pointer to 32-bit integers
/* then perform a 32-bit XOR if needed... */
from_s32 = (UINT32*) from_s; // pointer to 32-bit integers
if ( (symbolSize64 << 1) < symbolSize32)
{
(* (UINT32*) pt1++) ^= *from_s32;
(* (UINT32*) pt2++) ^= *from_s32;
(* (UINT32*) pt3++) ^= *from_s32;
(* (UINT32*) pt4++) ^= *from_s32;
(* (UINT32*) pt5++) ^= *from_s32;
(* (UINT32*) pt6++) ^= *from_s32;
(* (UINT32*) pt7++) ^= *from_s32;
(* (UINT32*) pt8++) ^= *from_s32;
from_s32++;
}
if (symbolSize32rem > 0)
{
UINT8* s8;
for (i = 0; i < symbolSize32rem; i++)
{
s8 = ( (UINT8*) from_s32 + i);
(* (UINT8*) ( (UINT8*) pt1 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt2 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt3 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt4 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt5 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt6 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt7 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt8 + i)) ^= * (UINT8*) s8;
}
}
}
while (to_size >= 4)
{
UINT32 *from_s32; // to pointer to 32-bit integers
from_s = (UINT64*) from; // to pointer to 64-bit integers
pt1 = (UINT64*)to[0];
pt2 = (UINT64*)to[1];
pt3 = (UINT64*)to[2];
pt4 = (UINT64*)to[3];
to += 4;
to_size -= 4;
for (i = symbolSize64; i > 0; i--)
{
from_value = *from_s;
*pt1 ^= from_value;
*pt2 ^= from_value;
*pt3 ^= from_value;
*pt4 ^= from_value;
from_s++;
pt1++;
pt2++;
pt3++;
pt4++;
}
/* then perform a 32-bit XOR if needed... */
from_s32 = (UINT32*) from_s;
if ( (symbolSize64 << 1) < symbolSize32)
{
(* (UINT32*) pt1++) ^= *from_s32;
(* (UINT32*) pt2++) ^= *from_s32;
(* (UINT32*) pt3++) ^= *from_s32;
(* (UINT32*) pt4++) ^= *from_s32;
from_s32++;
}
if (symbolSize32rem > 0)
{
UINT8 *s8;
for (i = 0; i < symbolSize32rem; i++)
{
s8 = ( (UINT8*) from_s32 + i);
(* (UINT8*) ( (UINT8*) pt1 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt2 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt3 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt4 + i)) ^= * (UINT8*) s8;
}
}
}
while (to_size >= 2)
{
UINT32 *from_s32; // to pointer to 32-bit integers
from_s = (UINT64*) from; // to pointer to 64-bit integers
pt1 = (UINT64*)to[0];
pt2 = (UINT64*)to[1];
to += 2;
to_size -= 2;
for (i = symbolSize64; i > 0; i--)
{
*pt1 ^= *from_s ;
*pt2 ^= *from_s ;
from_s++;
pt1++;
pt2++;
}
/* then perform a 32-bit XOR if needed... */
from_s32 = (UINT32*) from_s; // pointer to 32-bit integers
if ( (symbolSize64 << 1) < symbolSize32)
{
(* (UINT32*) pt1++) ^= *from_s32;
(* (UINT32*) pt2++) ^= *from_s32;
from_s32++;
}
if (symbolSize32rem > 0)
{
UINT8 *s8;
for (i = 0; i < symbolSize32rem; i++)
{
s8 = ( (UINT8*) from_s32 + i);
(* (UINT8*) ( (UINT8*) pt1 + i)) ^= * (UINT8*) s8;
(* (UINT8*) ( (UINT8*) pt2 + i)) ^= * (UINT8*) s8;
}
}
}
if (to_size == 0) return;
UINT64 *t = (UINT64*) to[0]; // to pointer to 64-bit integers
UINT64 *f = (UINT64*) from; // from pointer to 64-bit integers
for (i = symbolSize64; i > 0; i--)
{
*t ^= *f;
t++;
f++;
}
UINT32* t32 = (UINT32*) t; // to pointer to 32-bit integers
UINT32 *f32 = (UINT32*) f; // from pointer to 32-bit integers
/* then perform a 32-bit XOR if needed... */
if ( (symbolSize64 << 1) < symbolSize32)
{
* (UINT32*) t32 ^= * (UINT32*) f32;
t32++;
f32++;
}
/* finally perform as many 8-bit XORs as needed if symbol size is not
* multiple of 32 bits... */
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) t32 + i) ^= * (UINT8*) ( (UINT8*) f32 + i);
}
}
#else //defined (__LP64__) || (__WORDSIZE == 64) } {
/*
* 32-bit machines
*/
while (to_size > 0)
{
UINT32 *t32 = (UINT32*) to[0]; // to pointer to 32-bit integers
UINT32 *f32 = (UINT32*) from; // from pointer to 32-bit integers
to++ ;
to_size-- ;
/* First perform as many 32-bit XORs as needed... */
for (i = symbolSize32; i > 0; i--)
{
*t32 ^= *f32;
t32++;
f32++;
}
/* finally perform as many 8-bit XORs as needed if symbol size is not
* multiple of 32 bits... */
if (symbolSize32rem > 0)
{
for (i = 0; i < symbolSize32rem; i++)
{
* (UINT8*) ( (UINT8*) t32 + i) ^= * (UINT8*) ( (UINT8*) f32 + i);
}
}
}
#endif //defined (__LP64__) || (__WORDSIZE == 64) }
//#else /* } ASSEMBLY_SSE_OPT { */
//#endif /* } ASSEMBLY_SSE_OPT */
}
#define NS 30
#define SZ 5
int main() {
void **to = calloc(NS, sizeof(void*));
for (int i = 0; i < NS; i++) {
to[i] = calloc(SZ, 1);
memset(to[i], 0xaa, SZ);
}
void *from = calloc(SZ, 1);
memset(from, 0xcc, SZ);
of_add_to_multiple_symbols(to, from, NS, SZ);
for (int i = 0; i < NS; i++) {
for (int j = 0; j < SZ; j++) {
printf("%02x ", ((uint8_t**)to)[i][j]);
}
printf("\n");
}
return 0;
}
valgrind ./a.out
==5914== Memcheck, a memory error detector
==5914== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==5914== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==5914== Command: ./a.out
==5914==
==5914== Invalid read of size 1
==5914== at 0x1094CD: of_add_to_multiple_symbols (of.c:102)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a178 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x1094EB: of_add_to_multiple_symbols (of.c:102)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a178 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x1094FD: of_add_to_multiple_symbols (of.c:103)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a1c8 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x10951B: of_add_to_multiple_symbols (of.c:103)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a1c8 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x10952D: of_add_to_multiple_symbols (of.c:104)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a218 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x10954B: of_add_to_multiple_symbols (of.c:104)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a218 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x10955D: of_add_to_multiple_symbols (of.c:105)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a268 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x10957B: of_add_to_multiple_symbols (of.c:105)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a268 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x10958A: of_add_to_multiple_symbols (of.c:106)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a2b8 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x1095A5: of_add_to_multiple_symbols (of.c:106)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a2b8 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x1095B4: of_add_to_multiple_symbols (of.c:107)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a308 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x1095CF: of_add_to_multiple_symbols (of.c:107)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a308 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x1095DE: of_add_to_multiple_symbols (of.c:108)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a358 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x1095F9: of_add_to_multiple_symbols (of.c:108)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a358 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x109608: of_add_to_multiple_symbols (of.c:109)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a3a8 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x109623: of_add_to_multiple_symbols (of.c:109)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a3a8 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x109844: of_add_to_multiple_symbols (of.c:153)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a8f8 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x109862: of_add_to_multiple_symbols (of.c:153)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a8f8 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x109874: of_add_to_multiple_symbols (of.c:154)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a948 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x109892: of_add_to_multiple_symbols (of.c:154)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a948 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x1098A4: of_add_to_multiple_symbols (of.c:155)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a998 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x1098C2: of_add_to_multiple_symbols (of.c:155)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a998 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x1098D4: of_add_to_multiple_symbols (of.c:156)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a9e8 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x1098F2: of_add_to_multiple_symbols (of.c:156)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8a9e8 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x109A5E: of_add_to_multiple_symbols (of.c:192)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8aa38 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x109A7C: of_add_to_multiple_symbols (of.c:192)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8aa38 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid read of size 1
==5914== at 0x109A8E: of_add_to_multiple_symbols (of.c:193)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8aa88 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
==5914== Invalid write of size 1
==5914== at 0x109AAC: of_add_to_multiple_symbols (of.c:193)
==5914== by 0x109C9B: main (of.c:275)
==5914== Address 0x4a8aa88 is 3 bytes after a block of size 5 alloc'd
==5914== at 0x4837B65: calloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5914== by 0x109C22: main (of.c:268)
==5914==
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
66 66 66 66 aa
==5914==
==5914== HEAP SUMMARY:
==5914== in use at exit: 395 bytes in 32 blocks
==5914== total heap usage: 33 allocs, 1 frees, 1,419 bytes allocated
==5914==
==5914== LEAK SUMMARY:
==5914== definitely lost: 245 bytes in 2 blocks
==5914== indirectly lost: 150 bytes in 30 blocks
==5914== possibly lost: 0 bytes in 0 blocks
==5914== still reachable: 0 bytes in 0 blocks
==5914== suppressed: 0 bytes in 0 blocks
==5914== Rerun with --leak-check=full to see details of leaked memory
==5914==
==5914== For counts of detected and suppressed errors, rerun with: -v
==5914== ERROR SUMMARY: 60 errors from 28 contexts (suppressed: 0 from 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment