How can I make custom malloc / free?

support for the ARM toolchain
Dirbaio
Posts: 5
Joined: Sun Jul 25, 2010 7:55 pm

How can I make custom malloc / free?

Post by Dirbaio » Sun Jul 25, 2010 8:01 pm

So, basically I want to implement my custom malloc and free, overriding libc ones.

I've tried the following without success:

- Malloc hooks: they don't exist in devkitarm :(
- Defining my own malloc / free functions: Works, but some functions from libc (printf related) call _malloc_r and _free_r, which i'm not intercepting.

How could I do it?
Thanks in advance!

WinterMute
Site Admin
Posts: 1986
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: How can I make custom malloc / free?

Post by WinterMute » Mon Jul 26, 2010 9:32 pm

I'm really not sure how easy this will be to do, I'll need to do some digging in newlib.

malloc and free call _malloc_r and _free_r respectively so intercepting those might work.

What's this for anyway?
Help keep devkitPro toolchains free, Donate today

Personal Blog

Dirbaio
Posts: 5
Joined: Sun Jul 25, 2010 7:55 pm

Re: How can I make custom malloc / free?

Post by Dirbaio » Tue Jul 27, 2010 9:17 am

I need it for two reasons:

- For debugging: I have weird memory corruption issues :(
- For ROM Hacking (in particular NSMB Hacking): I've set up some linker scripts that allow me to write some asm/c/c++ code and insert it into the game. I need malloc/free to call the actuall malloc/free from the game, or else i can't use dynamic memory, libc, libfat and lots of cool things i'd like to use...

I did try to intercept _malloc_r and _free_r too. I just wasn't able because there was soooo much shit:

Code: Select all


#if __STD_C
Void_t* mALLOc(RARG size_t bytes)
#else
Void_t* mALLOc(RARG bytes) RDECL size_t bytes;
#endif
{
#ifdef MALLOC_PROVIDED

  return malloc (bytes); // Make sure that the pointer returned by malloc is returned back.

#else

  mchunkptr victim;                  /* inspected/selected chunk */
  INTERNAL_SIZE_T victim_size;       /* its size */
  int       idx;                     /* index for bin traversal */
  mbinptr   bin;                     /* associated bin */
  mchunkptr remainder;               /* remainder from a split */
  long      remainder_size;          /* its size */
  int       remainder_index;         /* its bin index */
  unsigned long block;               /* block traverser bit */
  int       startidx;                /* first bin of a traversed block */
  mchunkptr fwd;                     /* misc temp for linking */
  mchunkptr bck;                     /* misc temp for linking */
(blah)

Right now, i've been able to get something working by copying the entire libc source code into my project, modifying malloc.c and compiling everything together.
However, that gives lots of problems. For example, when you just link to libc.a, the linker is smart and only links the .o's from libc.a that are needed. But if I put all the libc source code, everything is compiled and linked no matter if they are used or not :( so i get more or less 100kb more of code. That's only a temporary solution...

So, I'm still interested in more "elegant" ways for doing this :)
Thanks!

elhobbs
Posts: 358
Joined: Thu Jul 02, 2009 1:19 pm

Re: How can I make custom malloc / free?

Post by elhobbs » Tue Jul 27, 2010 3:45 pm

are you thinking that there are memory issues outside of your code - in libnds or newlib?

Dirbaio
Posts: 5
Joined: Sun Jul 25, 2010 7:55 pm

Re: How can I make custom malloc / free?

Post by Dirbaio » Tue Jul 27, 2010 7:01 pm

Nope :)

I dont want custom mallocs because I think that the default ones are bugged.
With custom mallocs you can do very good debugging.

For instance, what i have now is this: http://dirbaio.pastebin.com/UaHqxWfa
What it does is allocate the memory from the beginning of RAM, and each allocated block has around it a reserved area filled with constant data. When you do a free(), it checks if the data is still there, so it can see if you're writing out of the bounds of an array or similar things.

It can catch silly errors like

u8* ptr = new u8[100];
delete[] ptr;
delete[] ptr; //Twice!!

and like

u8* ptr = new u8[10];
ptr[11]=1;
delete[] ptr;

zeromus
Posts: 212
Joined: Wed Mar 31, 2010 6:05 pm

Re: How can I make custom malloc / free?

Post by zeromus » Tue Jul 27, 2010 9:37 pm

if you just want to catch your own silly errors then only use new and delete and override them

User avatar
Izhido
Posts: 107
Joined: Fri Oct 19, 2007 10:57 pm
Location: Costa Rica
Contact:

Re: How can I make custom malloc / free?

Post by Izhido » Wed Jul 28, 2010 2:02 pm

Umm... could you please elaborate a little more on this thing about default malloc / free being "bugged"?

User avatar
vuurrobin
Posts: 219
Joined: Fri Jul 11, 2008 8:49 pm
Location: The Netherlands
Contact:

Re: How can I make custom malloc / free?

Post by vuurrobin » Wed Jul 28, 2010 2:32 pm

its not the default malloc/free that is bugged, but by overriding malloc and free, you can keep better track of memory allocation/freeing to find memory leaks and stuff.

cdmac
Posts: 10
Joined: Tue Jul 13, 2010 8:00 pm

Re: How can I make custom malloc / free?

Post by cdmac » Sun Aug 08, 2010 12:12 pm

The GNU linker allows you to override functions. It can be useful for globally disabling printf()s in crappy middleware and libraries in release builds.

Here's a forum post explaining how to use it with malloc. The same thing would apply for free/realloc.

http://www.linuxquestions.org/questions ... nt-790444/

WinterMute
Site Admin
Posts: 1986
Joined: Tue Aug 09, 2005 3:21 am
Location: UK
Contact:

Re: How can I make custom malloc / free?

Post by WinterMute » Sun Aug 08, 2010 4:02 pm

That's awesome, just tested with devkitARM, thanks cdmac.

Code: Select all

void *__real__malloc_r(struct _reent*r, size_t size);

void *__wrap__malloc_r(struct _reent*r, size_t size) {
	iprintf("my malloc\n");
	/* do this or write your own allocator */
	return __real_malloc_r(r,size);
}

and add -Wl,-wrap,_malloc_r to your LDFLAGS in the makefile. The linker then prefixes the real function with __real_ and your override with __wrap_

Code: Select all

LDFLAGS	=	-specs=ds_arm9.specs -g $(ARCH) -Wl,-wrap,_malloc_r -Wl,-Map,$(notdir $*.map)
Help keep devkitPro toolchains free, Donate today

Personal Blog

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest