Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory allocation optimization: from heap to stack

I am doing some reverse engineering tasks towards binaries on 32-bit x86 architecture.

Recently I found some interesting optimizations from C source code to assembly program.

For example, the original source code is like (this source code is from openssl library):

powerbufFree = (unsigned char *)malloc(powerbufLen);

And after compilation (gcc version 4.8.4 -O3), the assembly code is like this:

807eaa0: cmp eax, 0xbff                         # eax holds the length of the buf.
807eaa5: mov dword ptr [ebp-0x68], eax          # store the length of powerbuf on the stack
807eaa8: jnle 0x807ec60                         # 0x807ec60 refers to the malloc
807eaae: mov edx, eax
807eab0: add eax, 0x5e
807eab3: and eax, 0xfffffff0
807eab6: sub esp, eax
807eab8: lea eax, ptr [esp+0x23]
807eabc: and eax, 0xffffffc0
807eabf: add eax, 0x40
807ead3: mov dword ptr [ebp-0x60], eax  # store the base addr of the buf on the stack.

To my surprise, the buf is indeed allocated on the stack!!! It seems like an optimization for heap allocator for me, but I am not sure.

So here is my question, does the above optimization (malloc --> stack allocation) seems familar to anyone? Does it make sense? Could anyone provide some manual/specification on such optimization?

like image 943
lllllllllllll Avatar asked Jun 23 '16 02:06

lllllllllllll


People also ask

Are allocations faster on stack or heap?

Because the data is added and removed in a last-in-first-out manner, stack-based memory allocation is very simple and typically much faster than heap-based memory allocation (also known as dynamic memory allocation) e.g. C's malloc .

Why is memory allocation in stack faster than heap?

The stack is faster because the access pattern makes it trivial to allocate and deallocate memory from it (a pointer/integer is simply incremented or decremented), while the heap has much more complex bookkeeping involved in an allocation or free.

What is difference between stack and heap memory allocation?

Heap memory is used by all the parts of the application whereas stack memory is used only by one thread of execution. Whenever an object is created, it's always stored in the Heap space and stack memory contains the reference to it.

What is heap optimization?

This technique lets the allocator reclaim memory faster, and allows it to be immediately used for new heap objects, which, over time, reduces the maximum amount of memory required. Always attempt to free objects in the same function as they are allocated, unless it is an allocation function.


1 Answers

From the source of bn_exp.c:

0634 #ifdef alloca
0635     if (powerbufLen < 3072)
0636         powerbufFree = alloca(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH);
0637     else
0638 #endif
0639     if ((powerbufFree=(unsigned char*)OPENSSL_malloc(powerbufLen+MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL)
0640         goto err;

Note that 0xbff is equal to 3071. On systems that support it, alloca does stack allocation. This is true of the GNU version, which is used by Linux, and BSD implementations copied this API from 32V UNIX from AT&T (according to FreeBSD).

You only looked at line 639. But if alloca is defined, then the C code matches up to your assembly.

The optimization itself is often used to avoid the expense of using malloc for a temporary buffer if the allocation is relatively small. For C.1999, a VLA could be used instead (since C.2011, VLA is an optional feature).

Sometimes, the optimization just uses a fixed size buffer of some reasonable smallish size. For example:

char tmp_buf[1024];
char *tmp = tmp_buf;

if (bytes_needed > 1024) {
    tmp = malloc(bytes_needed);
}
/* ... */
if (tmp != tmp_buf) {
    free(tmp);
}
like image 94
jxh Avatar answered Sep 18 '22 12:09

jxh