size和objdump报告文本段

时间:2015-07-05 04:29:05

标签: c linux gcc

我已经尝试了这一点,但坚持下面的答案hello_world-1.c

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

执行的命令:

[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

有人可以帮我弄清楚下面问题可能是什么原因吗?

  1. size命令没有列出hello_worldhello_world.o的堆栈或堆段。这背后可能是什么原因? (对于上面的问题,答案是因为我没有调用任何函数,也没有使用任何堆段,这就是为什么它们没有出现在这里。我是否正确?)
  2. hello_world-1.c中有无全局变量。为什么size报告对象文件数据 bss 零长度,但< 可执行文件的强>非零长度
  3. sizeobjdump报告文本细分不同尺寸。你能否告知差异来自何处?
  4. 我已经尝试但未能就上述3个问题做出结论。感谢你的帮助。

2 个答案:

答案 0 :(得分:11)

1)操作系统在运行时创建堆和堆栈;也就是说,在将可执行文件加载到虚拟内存之后。因此,它们不是可执行文件的一部分。

2)因为可执行文件还包含来自链接器链接到目标文件的stdio库的数据和代码,所以请注意。

3)因为size,这样调用(没有任何参数)根据伯克利惯例显示大小。在这种情况下,text条目会报告三个不同细分的组合大小:

.text

.rodata

.eh_frame

另一方面,objdump仅报告.text的大小。如果根据SysV约定调用它,.text.rodata.eh_frame的大小可以单独显示size,如下所示:size -A hello_world-1.cobjdump。然后,您将看到与 <div class="row"> <div class="cell" id="jobtitle"></div> <div class="cell" id="jobname"></div> <div class="cell" id="fullname"></div> <div class="cell" id="phone"></div> <div class="cell" id="mail"></div> <div class="cell" id="city"></div> <div class="cell" id="description"></div> </div> 完全相同的信息。

希望这有帮助。

答案 1 :(得分:3)

问题#2。 这是因为在完成链接以创建可执行文件时,定义的默认全局变量很少。下面的命令可以显示符号表。两个变量,每个4个字节是__data_start和__bss_start。

objdump -x hello_world-1

0000000000601030 g .data 0000000000000000 __data_start

0000000000601034 g .bss 0000000000000000 __bss_start

问题#1 可执行文件中不会提及堆栈和堆,因为它们是由OS动态分配的。二进制文件仅提供静态的部分。比如,数据,文本和数据的内容和大小。 bss段在编译时固定。

问题#3 检查大小util的来源 https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=binutils/size.c;h=dcfd9547b25cdd58db890f9fe0dc9a3ba9228d89;hb=HEAD#l449

它将所有ReadOnly / Code部分添加为文本。即

 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 }

因此,如果您获取objdump的输出并添加所有只读/代码段,那么您将获得值1222