Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- // Declare the functions so they can be defined later and are linked to their correct identifiers
- #define malloc malloc_%RANDOM%
- #define aligned_alloc aligned_alloc_%RANDOM%
- #define calloc calloc_%RANDOM%
- #define realloc realloc_%RANDOM%
- #define free free_%RANDOM%
- void* malloc(unsigned int sz);
- void* aligned_alloc(unsigned int alignment, unsigned int sz);
- void* calloc(unsigned int num, unsigned int sz);
- void* realloc(void* ptr, unsigned int sz);
- void free(void* ptr);
- #define main user_main_%RANDOM%
- // User code
- int main(int argc, char** argv) {
- return 0;
- }
- // End of user code
- #define MALLOC_MEM_BLOCK_SIZE_%RANDOM% 1024
- #define MALLOC_MEM_BLOCK_COUNT_%RANDOM% 1024
- #define MALLOC_MEM_BLOCK_COUNT_PRE_%RANDOM% 1024
- #define MALLOC_MEM_BLOCK_COUNT_POST_%RANDOM% 1024
- struct t_memory_%RANDOM%{
- struct {
- void(*init_memory)();
- void(*check_memory_after_end)();
- void*(*malloc_init_block)(int, unsigned int);
- void*(*malloc)(unsigned int);
- void(*free)(void*);
- void*(*realloc)(void* ptr, unsigned int sz);
- void*(*calloc)(unsigned int num, unsigned int sz);
- void*(*aligned_alloc)(unsigned int alignment, unsigned int sz);
- } functions;
- int(*userMain)(int, char**);
- struct {
- char used;
- unsigned int sz;
- char memoryPre[MALLOC_MEM_BLOCK_COUNT_PRE_%RANDOM%];
- char memory[MALLOC_MEM_BLOCK_SIZE_%RANDOM%];
- char memoryPost[MALLOC_MEM_BLOCK_COUNT_POST_%RANDOM%];
- } mallocated_memory[MALLOC_MEM_BLOCK_COUNT_%RANDOM%];
- int MALLOC_MEM_BLOCK_COUNT;
- int MALLOC_MEM_BLOCK_SIZE;
- int MALLOC_MEM_BLOCK_COUNT_PRE;
- int MALLOC_MEM_BLOCK_COUNT_POST;
- struct {
- int used_blocks;
- int available_blocks;
- int last_init_block;
- int available_allocations;
- } config;
- struct {
- int mem_leaks;
- int invalid_frees;
- int invalid_realloc;
- int zero_allocs;
- int negative_allocs;
- int big_allocs;
- int too_many_allocs;
- int writes_before;
- int writes_beyond;
- } stats;
- } memory_%RANDOM%;
- void check_memory_after_end_%RANDOM%() {
- struct t_memory_%RANDOM%* mem = &memory_%RANDOM%;
- for(int i = 0; i < mem->config.last_init_block; i++) {
- if(mem->mallocated_memory[i].used){
- mem->stats.mem_leaks++;
- }
- }
- if (
- mem->stats.mem_leaks > 0 ||
- mem->stats.invalid_frees > 0 ||
- mem->stats.zero_allocs > 0 ||
- mem->stats.negative_allocs > 0 ||
- mem->stats.big_allocs > 0 ||
- mem->stats.too_many_allocs > 0 ||
- mem->stats.writes_before > 0 ||
- mem->stats.writes_beyond > 0 ||
- mem->stats.invalid_realloc > 0
- ) {
- printf("Memory Error: "
- "leaks: %d, "
- "invalid frees: %d, "
- "zero mallocs: %d, "
- "negative mallocs: %d, "
- "big mallocs: %d, "
- "too many allocs: %d, "
- "writes beyond: %d, "
- "writes before: %d, "
- "invalid realloc: %d, ",
- mem->stats.mem_leaks,
- mem->stats.invalid_frees,
- mem->stats.zero_allocs,
- mem->stats.negative_allocs,
- mem->stats.big_allocs,
- mem->stats.too_many_allocs,
- mem->stats.writes_before,
- mem->stats.writes_beyond,
- mem->stats.invalid_realloc
- );
- }
- }
- void* malloc_init_block_%RANDOM%(int blockIndex, unsigned int sz) {
- struct t_memory_%RANDOM%* mem = &memory_%RANDOM%;
- mem->mallocated_memory[blockIndex].used = 1;
- for(int o = 0; o < mem->MALLOC_MEM_BLOCK_COUNT_PRE; o++) {
- mem->mallocated_memory[blockIndex].memoryPre[o] = 0;
- }
- for(int o = 0; o < mem->MALLOC_MEM_BLOCK_COUNT_POST; o++) {
- mem->mallocated_memory[blockIndex].memoryPost[o] = 0;
- }
- for(int o = 0; o < mem->MALLOC_MEM_BLOCK_SIZE; o++) {
- mem->mallocated_memory[blockIndex].memory[o] = 0;
- }
- mem->mallocated_memory[blockIndex].used = 1;
- mem->config.used_blocks++;
- mem->mallocated_memory[blockIndex].sz = sz;
- return &(mem->mallocated_memory[blockIndex].memory);
- }
- void* malloc(unsigned int sz) {
- struct t_memory_%RANDOM%* mem = &memory_%RANDOM%;
- if(mem->config.available_allocations < 0) {
- mem->config.available_allocations = mem->MALLOC_MEM_BLOCK_COUNT;
- }
- if (mem->config.used_blocks >= mem->config.available_allocations) {
- return 0;
- }
- if(sz > (unsigned int) mem->MALLOC_MEM_BLOCK_SIZE) {
- mem->stats.big_allocs++;
- return 0;
- } else if( ((int)sz) < 0) {
- mem->stats.negative_allocs++;
- return 0;
- } else if(sz == 0) {
- mem->stats.zero_allocs++;
- return 0;
- }
- if(mem->config.used_blocks == mem->MALLOC_MEM_BLOCK_COUNT) {
- return 0;
- } else {
- for(int i = 0; i < mem->config.last_init_block; i++) {
- if(mem->mallocated_memory[i].used == 0) {
- return mem->functions.malloc_init_block(i, sz);
- }
- }
- mem->config.last_init_block++;
- return mem->functions.malloc_init_block(mem->config.last_init_block - 1, sz);
- }
- }
- void free(void* ptr) {
- struct t_memory_%RANDOM%* mem = &memory_%RANDOM%;
- for(int i = 0; i < mem->config.last_init_block; i++) {
- if((&(mem->mallocated_memory[i].memory)) == ptr) { // Our memory
- if (mem->mallocated_memory[i].used != 1) { // Should never happen
- mem->stats.invalid_frees++;
- } else {
- mem->mallocated_memory[i].used = 0;
- mem->config.used_blocks--;
- }
- // No clearing, next malloc clears, if needed
- for(int o = mem->mallocated_memory[i].sz; o < mem->MALLOC_MEM_BLOCK_SIZE; o++) {
- if(mem->mallocated_memory[i].memory[o] != 0){
- mem->stats.writes_beyond++;
- }
- }
- for(int o = 0; o < mem->MALLOC_MEM_BLOCK_COUNT_PRE; o++) {
- if(mem->mallocated_memory[i].memoryPre[o] != 0){
- mem->stats.writes_before++;
- }
- }
- for(int o = 0; o < mem->MALLOC_MEM_BLOCK_COUNT_POST; o++) {
- if(mem->mallocated_memory[i].memoryPost[o] != 0){
- mem->stats.writes_beyond++;
- }
- }
- return;
- }
- }
- // No our memory, freeing whatever bad
- mem->stats.invalid_frees++;
- }
- void* calloc(unsigned int num, unsigned int sz) {
- struct t_memory_%RANDOM%* mem = &memory_%RANDOM%;
- return mem->functions.malloc(num*sz);
- }
- void* realloc(void* ptr, unsigned int sz) {
- struct t_memory_%RANDOM%* mem = &memory_%RANDOM%;
- // Find the memory
- for(int i = 0; i < mem->config.last_init_block; i++) {
- if((&(mem->mallocated_memory[i].memory)) == ptr) { // Our memory
- if (mem->mallocated_memory[i].used != 1) { // Should never happen
- mem->stats.invalid_realloc++;
- return 0;
- } else {
- // Check for corruptions before extending. Twice the severity, twice the errors
- for(int o = mem->mallocated_memory[i].sz; o < mem->MALLOC_MEM_BLOCK_SIZE; o++) {
- if(mem->mallocated_memory[i].memory[o] != 0){
- mem->stats.invalid_realloc++;
- mem->stats.writes_beyond++;
- }
- }
- for(int o = 0; o < mem->MALLOC_MEM_BLOCK_COUNT_PRE; o++) {
- if(mem->mallocated_memory[i].memoryPre[o] != 0){
- mem->stats.invalid_realloc++;
- mem->stats.writes_before++;
- }
- }
- for(int o = 0; o < mem->MALLOC_MEM_BLOCK_COUNT_POST; o++) {
- if(mem->mallocated_memory[i].memoryPost[o] != 0){
- mem->stats.invalid_realloc++;
- mem->stats.writes_beyond++;
- }
- }
- // No corruptions, check for size
- if(sz > (unsigned int) mem->MALLOC_MEM_BLOCK_SIZE) {
- mem->stats.big_allocs++;
- return 0;
- } else if( ((int)sz) < 0) {
- mem->stats.negative_allocs++;
- return 0;
- } else if(sz == 0) {
- mem->stats.zero_allocs++;
- return 0;
- }
- if (mem->mallocated_memory[i].sz < sz) { // Trimming -> zero fill the extension
- for(unsigned int o = sz; o < mem->mallocated_memory[i].sz; o++) {
- mem->mallocated_memory[i].memory[o] = 0;
- }
- }
- mem->mallocated_memory[i].sz = sz;
- return &(mem->mallocated_memory[i].memory);
- }
- }
- }
- mem->stats.invalid_realloc++;
- return 0;
- }
- void* aligned_alloc(unsigned int alignment, unsigned int sz) {
- struct t_memory_%RANDOM%* mem = &memory_%RANDOM%;
- if(sz % alignment > 0) {
- mem->stats.negative_allocs++;
- return 0;
- }
- // lol, no
- return mem->functions.malloc(sz);
- }
- void init_memory_%RANDOM%() {
- // No memset
- char* data = (char*) &memory_%RANDOM%;
- for(unsigned int i = 0; i < sizeof(struct t_memory_%RANDOM%); i++) {
- data[i] = 0;
- }
- struct t_memory_%RANDOM%* mem = &memory_%RANDOM%;
- mem->MALLOC_MEM_BLOCK_COUNT = MALLOC_MEM_BLOCK_COUNT_%RANDOM%;
- mem->MALLOC_MEM_BLOCK_SIZE = MALLOC_MEM_BLOCK_SIZE_%RANDOM%;
- mem->MALLOC_MEM_BLOCK_COUNT_PRE = MALLOC_MEM_BLOCK_COUNT_PRE_%RANDOM%;
- mem->MALLOC_MEM_BLOCK_COUNT_POST = MALLOC_MEM_BLOCK_COUNT_POST_%RANDOM%;
- mem->functions.init_memory = &init_memory_%RANDOM%;
- mem->functions.check_memory_after_end = &check_memory_after_end_%RANDOM%;
- mem->functions.malloc_init_block = &malloc_init_block_%RANDOM%;
- mem->functions.malloc = &malloc;
- mem->functions.aligned_alloc = &aligned_alloc;
- mem->functions.realloc = &realloc;
- mem->functions.calloc = &calloc;
- mem->functions.free = &free;
- mem->userMain = &main;
- }
- #ifdef main
- #undef main
- #endif
- // The real entry point
- int main(int argc, char** argv) {
- // Init the memory
- init_memory_%RANDOM%();
- struct t_memory_%RANDOM%* mem = &memory_%RANDOM%;
- // Segfault by default
- int result = -1;
- if(argc >= 2) {
- // Read total number of allocations available
- if(mem->config.available_allocations < 0) {
- mem->config.available_allocations = mem->MALLOC_MEM_BLOCK_COUNT;
- }
- int argAllocations = 0;
- int sign = 1;
- for(int i = 0; argv[1][i] != '\0';i++){
- char c = argv[1][i];
- if(c >= '0' && c <= '9') {
- argAllocations *= 10;
- argAllocations += c - '0';
- } else if (c == '-') { // ... but why?
- sign = -1;
- }
- }
- // And add the one we are about to do
- argAllocations++;
- mem->config.available_allocations = argAllocations * sign;
- // Create new argv base on the original one without the first argument
- char** anotherArgv = (char**) malloc(sizeof(char*) * (argc - 1));
- // Copy file name
- anotherArgv[0] = argv[0];
- // And every argument after that
- for(int i = 2; i < argc; i++) {
- anotherArgv[i-1] = argv[i];
- }
- // Call user main
- result = mem->userMain(argc-1, anotherArgv);
- // Destroy our allocated argv
- free(anotherArgv);
- // Check memory for errors
- mem->functions.check_memory_after_end();
- return result;
- }
- return result;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement