【问题标题】:size and objdump report different sizes for the text segmentsize 和 objdump 报告文本段的不同大小
【发布时间】:2015-07-05 04:29:04
【问题描述】:

我已经尝试过了,但坚持回答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 报告 databss 段对于 object file 的长度零长度,但 可执行文件的非零长度
  3. sizeobjdump 报告 文本段不同大小。您能否告知差异来自何处?

我已尝试但未能就上述 3 个问题得出结论。感谢您在这方面的帮助。

【问题讨论】:

  • 你没有全局变量,但你有全局数据:一个由 13 个chars 组成的数组,对应于你的字符串字面量。加上可能在stdio.h 中声明的任何内容。
  • 对于#3:size -A hello_world-1.o 显示的文本段大小是否更接近objdump 显示的大小?

标签: c linux gcc


【解决方案1】:

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

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

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

.text

.rodata

.eh_frame

另一方面,objdump 只报告.text 的大小。如果您根据 SysV 约定调用 size,则可以分别看到 .text.rodata.eh_frame 的大小,如下所示:size -A hello_world-1.c。然后您将看到与objdump 完全相同的信息。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

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

    objdump -x hello_world-1

    0000000000601030 g .data 0000000000000000 __data_start

    0000000000601034 g .bss 0000000000000000 __bss_start

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

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

    它将所有只读/代码部分的添加显示为文本。即

     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

    【讨论】:

      猜你喜欢
      • 2021-07-05
      • 2014-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-18
      • 1970-01-01
      • 2011-04-14
      相关资源
      最近更新 更多