Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

size and objdump report different sizes for the text segment

Tags:

c

linux

gcc

I have tried this, but stuck up to the answer below questions where hello_world-1.c is

#include<stdio.h>
int main(void)
{
    printf("Hello world\n");
    return 0;
}

The executed commands:

[kishore@localhost-localdomain ~]$ gcc -Wall -Wextra -c hello_world-1.c
[kishore@localhost-localdomain ~]$ gcc -o hello_world-1 hello_world-1.o
[kishore@localhost-localdomain ~]$ size hello_world-1 hello_world-1.o

    text    data    bss     dec    hex    filename
    1222     280      4    1506    5e2    hello_world-1
     139       0      0     139     8b    hello_world-1.o

[kishore@localhost-localdomain ~]$ objdump -h hello_world-1.o

    hello_world-1.o:     file format elf32-i386

    Sections:
    Idx Name          Size      VMA       LMA       File off  Algn
      0 .text         0000003b  00000000  00000000  00000034  2**0
                      CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
      1 .data         00000000  00000000  00000000  0000006f  2**0
                      CONTENTS, ALLOC, LOAD, DATA
      2 .bss          00000000  00000000  00000000  0000006f  2**0
                      ALLOC
      3 .rodata       0000000c  00000000  00000000  0000006f  2**0
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
      4 .comment      0000002d  00000000  00000000  0000007b  2**0
                      CONTENTS, READONLY
      5 .note.GNU-stack 00000000  00000000  00000000  000000a8  2**0
                      CONTENTS, READONLY
      6 .eh_frame     00000044  00000000  00000000  000000a8  2**2
                      CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

Can anyone please help me to figure out what might be the reasons for the questions below?

  1. The size command didn't list a stack or heap segment for hello_world or hello_world.o. What might be the reason behind this? (for above question, the answer is as I didn't called any function and also not used any heap segment, that's why they didn't showed up here. Am I correct?)
  2. There are no global variables in hello_world-1.c. Why size reports that the data and bss segments have zero length for the object file but non-zero length for the executable?
  3. size and objdump report different sizes for the text segment. Can you please advise where the discrepancy comes from?

I have tried but failed to conclude on above 3 questions. Appreciate your help on this.

like image 505
KK- Avatar asked Jul 05 '15 04:07

KK-


2 Answers

1) Heap and stack are created by the OS at run time; that is, after the executable has been loaded into virtual memory. Therefore, they are not part of the executable file.

2) Because the executable also contains data -- and code, mind you -- from the stdio library that has been linked to the object file by the linker.

3) Because size, invoked like this (without any parameters) displays sizes according to the Berkeley convention. Under this scenario, the text entry reports the combined sizes of three different segments:

.text

.rodata

.eh_frame

On the other hand, objdump reports the size of .text only. You can see the sizes of .text, .rodata, and .eh_frame separately with size if you invoke it according to the SysV convention, like this: size -A hello_world-1.c. Then you will see exactly the same info you see with objdump.

Hope this helps.

like image 108
dmitry Avatar answered Sep 20 '22 02:09

dmitry


For Question #2. It is because there are few default global variables defined when the linking is done to create a executable. Below command can show the symbol table. Two variables each of 4 bytes are __data_start and __bss_start.

objdump -x hello_world-1

0000000000601030 g .data 0000000000000000 __data_start

0000000000601034 g .bss 0000000000000000 __bss_start

For question #1 Stack and Heap will not be mentioned in the executable because they are dynamically allocated by the OS. The binary file only provides sections that are static in nature. Like, contents and sizes of data, text & bss segments are fixed at compilation time.

For Question #3 Check the source of size util at https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=binutils/size.c;h=dcfd9547b25cdd58db890f9fe0dc9a3ba9228d89;hb=HEAD#l449.

It displays addition of all ReadOnly/Code sections as text. i.e

 446 static void
 447 berkeley_sum (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec,
 448               void *ignore ATTRIBUTE_UNUSED)
 449 {
 450   flagword flags;
 451   bfd_size_type size;
 452 
 453   flags = bfd_get_section_flags (abfd, sec);
 454   if ((flags & SEC_ALLOC) == 0)
 455     return;
 456 
 457   size = bfd_get_section_size (sec);
 458   if ((flags & SEC_CODE) != 0 || (flags & SEC_READONLY) != 0)
 459     textsize += size;
 460   else if ((flags & SEC_HAS_CONTENTS) != 0)
 461     datasize += size;
 462   else
 463     bsssize += size;
 464 }

So if you take the output of objdump and add all readonly/code sections then you will get value 1222

like image 27
Nithin Avatar answered Sep 19 '22 02:09

Nithin