Lately I found the bug in my mymalloc function.
Change really is in below lines:
                if (xsize == 0x7FFF) f = 1; //was (xsize<<1)+2 == 0) // 0x7FFF 
means empty
        else{
                heap_next = &heap_top[xsize + 1];
1:              if(heap_next >= heap_bottom ) f = 1;//f=1 mean do loop once and 
end if you 
reach over stack
                }

The basic disadvantage of below code is the way of description bit allocation.
When You overrun buffer you almost loose all data ie:
char * buffer = "abcd";
char* ptr = mymalloc(4); //you overrun buffer because '\0' deletes next and 
all above allocations. Moreover this improvement prevents deleting stack. 
however I have no idea where to put malloc information data. All ideas have 
pros and cons.



all code is below:
//released under GNU PUBLIC LICENCE
#include <stdlib.h>

#define XSIZE(x) ((*x)>>1)
#define FREE_P(x) (!((*x)&1))
#define MARK_BUSY(x) ((*x)|=1)
#define MARK_FREE(x) ((*x)&=0xfffe)

//extern size_t __bss_end;
extern size_t __noinit_end;
#define GET_HEAP_BOTTOM(__x)  __asm__ __volatile__("mov r1, %0": "=r" 
((uint16_t)__x) :)

void myfree (void *p);
void *mymalloc (size_t size);

void *mymalloc (size_t size)
{
    static char once;
    size_t * heap_bottom;
    size_t * heap_top = &__noinit_end;
        size_t * heap_next;
        size_t xsize;
    char f = 0;

    if (!once)
    {
        once = 1;
        *heap_top = 0xFFFE;
    }
    GET_HEAP_BOTTOM (heap_bottom);
    heap_bottom -= 20;
        
    size = (size+1)>>1; /* round to 2 */
    do
    {
    xsize = XSIZE (heap_top);
                if (xsize == 0x7FFF) f = 1; //(xsize<<1)+2 == 0)
        else{
                heap_next = &heap_top[xsize + 1];
                if(heap_next >= heap_bottom ) f = 1;
                }

        if (FREE_P (heap_top))
        {
            if (f>0)
            {
                xsize = heap_bottom - heap_top - 1;//(heap_b - heap_t)/2 in 
fact
            }
            else if (FREE_P(heap_next))
            {
                *heap_top = ( (XSIZE(heap_next)== 0x7FFF)/*<<1) + 2 == 0*/
                              ? 0xFFFE
                              : (xsize + XSIZE(heap_next) + 1)<<1);
                continue;
            }
                        
                        
            if (xsize >= size)
            {
                        
                if (f>0)
                    heap_top[size + 1] = 0xFFFE;
                else if (xsize != size)
                    heap_top[size + 1] = (xsize - size - 1) << 1;
                *heap_top = size << 1;
                MARK_BUSY (heap_top);
                return heap_top+1;
            }
        }
        heap_top += xsize + 1;
    }
    while (!f);
    return NULL;
}

void myfree (void *p)
{
    size_t *t = (size_t*)p - 1;
    MARK_FREE (t);
}



Reply via email to