Wymyśliłem coś takiego:
#include <stdio.h>
/* test hack */
typedef unsigned int size_t;
#define malloc(x) 0; \
char malloc_buf[x]; \
*((size_t*)((size_t)&malloc_buf+x)) = (size_t)malloc_buf;
#define free(x)
#define dbg(x) printf("0x%08x==0x%08x?\n", x, malloc_buf)
/* ... */
void test(){
char * p = malloc(10);
/* ... */
dbg(p); /* czy wskażnik p wskazuje na bufor? */
/* ... */
free(p);
}
int main(){
test();
return 0;
}
Wynik:
$ gcc -o test test.c && ./test
0xbf9670c2==0xbf9670c2?
Ale ta metoda mnie nie zadowala....
Wymyśliłem inną metodę:
malloc.S:
.global _malloc
_malloc:
pop %ebx /* adres powrotu */
movl (%esp), %eax /* argument */
sub %eax, %esp /* alokowanie na stosie */
push %eax /* zapamietanie ile zalokowano */
/* return */
mov %esp, %eax /* adres zalokowanego obszaru */
add $0x04, %eax /* pominiecie zapisanej wartosci wielkosci obszaru */
sub $0x20, %esp /* dodanie marginesu - pop'y argumentow w poprzedniej funkcji */
jmp *%ebx
.global _free
_free:
pop %ebx /* adres powrotu */
movl (%esp), %eax /* argument */
movl -0x04(%eax), %eax /* odczytanie wartosci wielkosci obszaru */
add $0x20, %esp /* zwolnienie marginesu */
add $0x04, %esp /* zwolnienie miejsca wartosci wielkosci obszaru */
add %eax, %esp /* zwolnienie zalokowanego obszaru */
jmp *%ebx
main.c:
#include <stdio.h>
volatile extern void * (_malloc)(unsigned int size);
extern void (_free)(void * p);
void test(){
size_t stack;
char * p;
asm("movl %%esp, %0\n" :"=r"(stack));
printf("przed alokacja:\n\t0x%08x\n", stack);
p = (char*)_malloc(0x100);
asm("movl %%esp, %0\n" :"=r"(stack));
printf("po alokacji:\n\t0x%08x\n", stack);
printf("adres wskaznika:\n\t0x%x\n", p);
/*
memset(p, 'A', 0x100);
p[0x100-1] = 0;
printf("%s\n", p);
*/
_free(p);
asm("movl %%esp, %0\n" :"=r"(stack));
printf("po zwolnieniu obszaru:\n\t0x%08x\n", stack);
return;
}
int main(){
test();
return 0;
}
Rezultat:
$ gcc -o main main.c malloc.S && ./main
przed alokacja:
0xbfba8d90
po alokacji:
0xbfba8c6c
adres wskaznika:
0xbfba8c80
po zwolnieniu obszaru:
0xbfba8d90
ŁF: w pierwszym poście wywaliłeś akurat to co było potrzebne, a to co nie potrzebne zostawiłeś.
/* ... */
typedef unsigned int size_t;
#define malloc(x) (void*)((size_t)&k - x ); char malloc_buf[x]
/* ... */
Aktualnie stosuję wstawkę asm.