Zamiana sposobu alokacji pamięci

0

Witam,

W kodzie mam coś takiego:

void func(){
  char * k = (char*)malloc(15);
  /* ... */
  free(k);
}

Chodzi o to że nie chcę korzystać z funkcji do dynamicznej alokacji pamięci, w tym przypadku jest to bezsensu i jest to marnowanie pamięci. W moim systemie nie mam zaimplementowanych takowych funkcji do alokacji, ze względu na to że chcę jak najbardziej zaoszczędzić na pamięci. Problem tkwi w tym, że nie mogę przerabiać kodu; jest źródło pewnego sterownika wziętego z linuksa i chciałbym zachować oryginalność kodu(wywalam tylko includy które odwołują się do plików systemowych i dodaje swój pliczek driver_hacks.h).

Nazwy wszystkich wskaźników do których jest przypisywany adres alokowanej pamięci są takie same - czyli k.
Na razie problem rozwiązałem robiąc:

driver_hacks.h:

#include <stdio.h>
#include <stdlib.h>

Jednak taki kod mnie nie zadowala; trzeba znać nazwy wskaźników, kompilator może trochę pomieszać i wskaźnik nie trafi na malloc_buf...
Ma ktoś jakiś fajny pomysł?;p

0

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1