0

I'm writing some code size analysis tool for my C program, using the output ELF file.

I'm using readelf -debug-dump=info to generate Dwarf format file.

I've noticed that My compiler is adding as a part of the optimization new consts, that are not in Dwarf file, to the .rodata section.

So .rodata section size includes their sizes but i don't have their sizes in Dwarf.

Here is an example fro map file:

*(.rodata)
 .rodata        0x10010000       0xc0 /<.o file0 path>
                0x10010000                const1
                0x10010040                const2

 .rodata        0x100100c0        0xa /<.o file1 path>

  fill         0x100100ca        0x6 

 .rodata        0x100100d0       0x6c /<.o file2 path>
                0x100100d0                const3
                0x100100e0                const4
                0x10010100                const5
                0x10010120                const6

    fill        0x1001013c        0x4 

In file1 above, although i didn't declare on const variable - the compiler does, this const is taking space in .rodata yet there is no symbol/name for it.

Here is the code inside some function that generates it:

uint8 arr[3][2] = {{146,179},
                   {133, 166},
                   {108, 141}} ;

So compiler add some consts values to optimize the load to the array.

How can i extract theses hidden additions from data sections?

I want to be able to fully characterize my code - How much space is used in each file, etc...

Clifford
  • 88,407
  • 13
  • 85
  • 165
ramsis
  • 13
  • 3
  • It is not clear what you are referring to and possibly your assumption of what these "constants" are is erroneous. It is certainly an X-Y problem. Include in your question your evidence, or what you are seeing, and ask what it is rather than asking how you can see "hidden" data - which Occam's Razor suggests does not actually exist.It seems more likely that your interpretation of the evidence is incorrect. – Clifford Mar 22 '18 at 19:10
  • Sure, have added an example. – ramsis Mar 23 '18 at 06:00
  • Perhaps also the code that generated this? Are they not perhaps simply constant initialisers for r/w data declared? – Clifford Mar 23 '18 at 07:55
  • Added, some example code! – ramsis Mar 24 '18 at 11:19
  • I'd like to extract those compiler additions sizes in memory. – ramsis Mar 24 '18 at 11:20
  • You are not helping - create a _small_ example, post _all_ the code, then post the map file content related to _that_ code. It is not possible to relate the fragment you have provided to the map file posted earlier. Moreover until I added the `;` it was not even valid code, so I have no confidence that this code has anything to do with the map file since it would not compile. – Clifford Mar 24 '18 at 13:54
  • Also the code fragment does not clarify the scope of `arr` - that will have an impact on how and when initialisation occurs and how the compiler and linker behave - context is everything - you have provided little context. Also avoid posting code and text with extraneous whirespace and hard tabs - it renders poorly on SO, and _do_ use code markup. I have so far fixed _all_your mark-up failures for you. – Clifford Mar 24 '18 at 14:18

2 Answers2

0

to get the size of elf file in details use

"You can use nm and size to get the size of functions and ELF sections.

To get the size of the functions (and objects with static storage duration):

$ nm --print-size --size-sort --radix=d tst.o The second column shows the size in decimal of function and objects.

To get the size of the sections:

$ size -A -d tst.o The second column shows the size in decimal of the sections."

Tool to analyze size of ELF sections and symbol

0

I am guessing here - it will be linker dependent, but when you have code such as:

uint8 arr[3][2] = {{146,179},
                   {133, 166},
                   {108, 141}} ;

arr at run-time exists in r/w memory, but its initialiser will be located in R/O memory to be copied to the R/W memory when the array is initialised. The linker need only provide the address, because the size will be known locally as a compile-time constant embedded as a literal in the initializing code. Consequently the size information does not appear in the map, because the linker discards that information.

Length is however implicit by the address of adjacent objects for filled space. So for example:

The size of const1 for example is equal to const2 - const1 and for const6 it is 0x1001013c - const6.

It is all rather academic however - you have precise control over this in terms of the size of your constant initialisers. They are not magically created data unrelated to your code, and I am not convinced that thy are a product of optimization as you suggest. The non-zero initialisers must exist regardless of optimisation options, and in any case optimisation primarily affects the size and/or speed of code (.text) rather then data. The impact on data sizes is likely to relate only to padding and alignment and in debug builds possibly "guard-space" for overrun detection.

However there is no need at all for you to guess. You can determine how this data is used by inspecting the disassembly or observing its execution (at the instruction level) in a debugger - to see exactly where initialised variables are copying the data from. You could even place an read-access break-point at these addresses and you will determine directly what code is utilizing them.

Clifford
  • 88,407
  • 13
  • 85
  • 165