'How are function sizes calculated by readelf

I am trying to understand how readelf utility calculates function size. I wrote a simple program

#include <stdio.h>

int main() {
    printf("Test!\n");
}

Now to check function size I used this (is this OK ? ):

readelf -sw a.out|sort -n -k 3,3|grep FUNC

which yielded:

 1: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.2.5 (2)
 2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (2)
29: 0000000000400470     0 FUNC    LOCAL  DEFAULT   13 deregister_tm_clones
30: 00000000004004a0     0 FUNC    LOCAL  DEFAULT   13 register_tm_clones
31: 00000000004004e0     0 FUNC    LOCAL  DEFAULT   13 __do_global_dtors_aux
34: 0000000000400500     0 FUNC    LOCAL  DEFAULT   13 frame_dummy
48: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@@GLIBC_2.2.5
50: 00000000004005b4     0 FUNC    GLOBAL DEFAULT   14 _fini
51: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_
58: 0000000000400440     0 FUNC    GLOBAL DEFAULT   13 _start
64: 00000000004003e0     0 FUNC    GLOBAL DEFAULT   11 _init
45: 00000000004005b0     2 FUNC    GLOBAL DEFAULT   13 __libc_csu_fini
60: 000000000040052d    16 FUNC    GLOBAL DEFAULT   13 main
56: 0000000000400540   101 FUNC    GLOBAL DEFAULT   13 __libc_csu_init

Now if I check the main function's size, it shows 16. How did it arrive at that? Is that the stack size ?

Compiler used gcc version 4.8.5 (Ubuntu 4.8.5-2ubuntu1~14.04.1)

GNU readelf (GNU Binutils for Ubuntu) 2.24



Solution 1:[1]

ELF symbols have an attribute st_size which specifies their size (see <elf.h>):

typedef struct
{
...
  Elf32_Word    st_size;                /* Symbol size */
...
} Elf32_Sym;

This attribute is generated by the toolchain generating the binary; e.g. when looking at the assembly code generated by the C compiler:

gcc -c -S test.c
cat test.s

you will see something like

        .globl  main
        .type   main, @function
main:
        ...
.LFE0:
        .size   main, .-main

where .size is a special as pseudo op.

update:

.size is the size of the code.

Here, .size gets assigned the result of . - main, where "." is the actual address and main the address where main() starts.

Solution 2:[2]

I found the problem. Someone put the code in our MongoDB wrapper to cast objects to arrays. So, the MongoDB\BSON\ObjectId was being converted to an array with a string element with key oid.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Guilherme Sampaio