This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

overloading malloc is impossible


I have no idea why this isn't working; but I'm trying to replace the
glibc allocator with something else via an LD_PRELOAD.  As a preliminary
step, I've decided to do something simple:  LD_PRELOAD something that
calls straight mmap() and see if it works.

No idea why, but 'ls' works, 'find' fails, 'xclock' works, and
'gcalctool' fails.  Most anything fails really.  I know the approach is
crude, but it's not broken.  Is there some secret trick to replacing
glibc's allocator?

Code attached if anyone wants to try this one.
-- 
John Moser <john.r.moser@gmail.com>
/* mmalloc.c
 * malloc with mmap()
 * GPL v2.0 or later at your discression
 */
/*
 * This is a proof-of-concept library that tests replacing malloc()
 */

#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>

#define PAGE_ALIGN(x) (4096 + x & ~4095)

void *calloc(size_t nmemb, size_t size) {
	return malloc(nmemb * size);
}

void *malloc(size_t size) {
	void *addr;

	if (!size) /*passed 0*/
		return NULL;

	/* Allocate using mmap() */
	addr = mmap(NULL, PAGE_ALIGN(size + sizeof(size_t)),
	  PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
	  0, 0);

	if (PAGE_ALIGN(size + sizeof(size_t)) < size)
		_exit(-220);

	*(size_t*)addr = size | 0x80000000;

	return addr + sizeof(size_t);
}

void free(void *ptr) {
	int size;
	void *addr;

	if (!ptr)
		return;

	addr = ptr - sizeof(size_t);
	size = *(size_t*)addr;

	/* Free with munmap() */
	if (size & 0x80000000)
		munmap(addr, PAGE_ALIGN(size & ~0x80000000 + sizeof(size_t)) );
	else // WTF?!
		_exit(-100);

	if (PAGE_ALIGN(size + sizeof(size_t)) < size)
		_exit(-220);

	return;
}

void *realloc(void *ptr, size_t size) {
	void *addr;
	void *newaddr;
	size_t mysize;

	if (!size) { /*passed 0*/
		free(ptr);
		return;
	}
	if (!ptr) /*no pointer*/
		return malloc(size);

	addr = ptr - sizeof(size_t);
	mysize =  *(size_t*)(addr);

	if (mysize & 0x80000000) { // do it ourself
		int i;
		newaddr = malloc(size);
		if (size < mysize)
			mysize = size;
		for (i = 0; i < mysize; i++)
			((char*)newaddr)[i] = ((char*)ptr)[i];
		free(ptr);
		return newaddr;
	}
	else
		_exit(-100);


	return addr;
}

Attachment: signature.asc
Description: This is a digitally signed message part


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]