size命令的sysv和berkeley格式差别

size命令使用说明

size命令用于显示二进制文件的段(节)大小,其功能类似于readelf -S,详细的说明如下:

用法:size [选项] [文件]
 显示二进制文件中节的大小
 没有给出输入文件,默认为 a.out
 The options are:
  -A|-B     --format={sysv|berkeley}  Select output style (default is berkeley)
  -o|-d|-x  --radix={8|10|16}         Display numbers in octal, decimal or hex
  -t        --totals                  Display the total sizes (Berkeley only)
            --common                  Display total size for *COM* syms
            --target=<bfdname>        Set the binary file format
            @<file>                   Read options from <file>
  -h        --help                    Display this information
  -v        --version                 Display the program's version

size:支持的目标: elf64-x86-64 elf32-i386 elf32-x86-64 a.out-i386-linux pei-i386  
pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big  
pe-x86-64 pe-i386 plugin srec symbolsrec verilog tekhex binary ihex

背景

size支持两种输出格式sysvberkeley,对同一个文件,看看执行效果有什么差异

[GMPY@11:41 tmp]$size test
   text    data     bss     dec     hex filename
   1810     584       8    2402     962 test
[GMPY@11:41 tmp]$size --format=sysv test
test  :
section              size      addr
...
.text                 640   4195616
...
.data                  16   6295624
.bss                    8   6295640
...
Total                2496

为了方便了解,这里补充以下3个重要段的功能:

段名功能
BSS存放程序中未初始化的全局变量的一块内存区域
DATA存放程序中已初始化的全局变量的一块内存区域
TEXT/CODE存放程序执行代码的一块内存区域

可以发现,test/data/bss段的大小不一致呀,我该相信哪一个?

源码

size命令是binutils软件包提供的子命令,在GNU的官网中找到其最新源码(2.32)

废话不多说,下载,解压,直接看源码(binutils/size.c)

static void
print_sizes (bfd *file)
{
  if (show_common)
    calculate_common_size (file);
  if (berkeley_format)
    print_berkeley_format (file);
  else
    print_sysv_format (file);
}

根据不同格式选择不同的打印方式,妥了,直接对比print_berkeley_formatprint_sysv_format

对比print_berkeley_format与print_sysv_format

berkeley格式

static void
print_berkeley_format (bfd *abfd)
{
  ...
  bsssize = 0;
  datasize = 0;
  textsize = 0;

  /*
   * 获取bss/data/text段大小
   * 找不到bfd_map_over_sections的定义,但猜测是一个宏
   * 功能:对每一个段调用berkeley_sum函数进行处理
   */
  bfd_map_over_sections (abfd, berkeley_sum, NULL);

  /* 打印信息头 */
  if (files_seen++ == 0)
    puts ((radix == octal) ? "   text\t   data\t    bss\t    oct\t    hex\tfilename" :
      "   text\t   data\t    bss\t    dec\t    hex\tfilename");

  /* 打印具体的数值 */
  rprint_number (7, textsize);
  putchar ('\t');
  rprint_number (7, datasize);
  putchar ('\t');
  rprint_number (7, bsssize);
  printf (((radix == octal) ? "\t%7lo\t%7lx\t" : "\t%7lu\t%7lx\t"),
      (unsigned long) total, (unsigned long) total);
  ...
}

sysv格式

static void
print_sysv_format (bfd *file)
{
  svi_total = 0;
  svi_maxvma = 0;
  svi_namelen = 0;

  /*
   * 获取bss/data/text段大小
   * 找不到bfd_map_over_sections的定义,但猜测是一个宏
   * 功能:对每一个段调用sysv_internal_printer函数进行处理
   */
  bfd_map_over_sections (file, sysv_internal_printer, NULL);
  if (show_common)
    {
      svi_total += common_size;
      sysv_one_line ("*COM*", common_size, 0);
    }
  ......
}

好吧,我们关注的是两者的数值差异,需要进一步对比子函数berkeley_sumsysv_internal_printer

对比berkeley_sum和sysv_internal_printer

berkeley格式

static void
berkeley_sum (bfd *abfd ATTRIBUTE_UNUSED, sec_ptr sec,
          void *ignore ATTRIBUTE_UNUSED)
{
  flagword flags;
  bfd_size_type size;

  flags = bfd_get_section_flags (abfd, sec);
  if ((flags & SEC_ALLOC) == 0)
    return;

  size = bfd_get_section_size (sec);

  /* 根据不同段的属性,进行不同类别的累加 */
  if ((flags & SEC_CODE) != 0 || (flags & SEC_READONLY) != 0)
    /* text/code 段 */
    textsize += size;
  else if ((flags & SEC_HAS_CONTENTS) != 0)
    /* data 段 */
    datasize += size;
  else
    /* bss 段 */
    bsssize += size;
}

sysv格式:

static void
sysv_one_line (const char *name, bfd_size_type size, bfd_vma vma)
{
  printf ("%-*s   ", svi_namelen, name);
  rprint_number (svi_sizelen, size);
  printf ("   ");
  rprint_number (svi_vmalen, vma);
  printf ("\n");
}

static void
sysv_internal_printer (bfd *file ATTRIBUTE_UNUSED, sec_ptr sec,
               void *ignore ATTRIBUTE_UNUSED)
{
  bfd_size_type size = bfd_section_size (file, sec);

  if (   ! bfd_is_abs_section (sec)
      && ! bfd_is_com_section (sec)
      && ! bfd_is_und_section (sec))
    {
      svi_total += size;

      /* 分别打印出每一个段的信息 */
      sysv_one_line (bfd_section_name (file, sec),
             size,
             bfd_section_vma (file, sec));
    }
}

结论

实锤了,berkeley格式与sysv格式下的bss/data/text是不同的含义,其中

  • sysv是实打实的打印出每一个段的大小,等效于readelf -S
  • berkeley是统计的结果,把代码段和只读的段统计到text段,把有内容的段统计到data段,其他全归属bss段

在只需要知道分类的统计结果时用berkelay格式,在需要明细到每一个段时采用sysv格式

转载于:https://www.cnblogs.com/gmpy/p/11376374.html

### 回答1: Linux下的size命令可以用于查看可执行文件、目标文件和共享库等二进制文件的大小,同时还可显示文件中各个段的大小信息。 size命令的使用格式如下: ``` size [选项] 文件名 ``` 常用选项包括: - -B:指定以字节为单位显示大小信息; - -t:按照段(section)的大小来显示信息; - -A:显示所有符号信息,包括未使用的符号等; - -G:显示全局变量的大小信息。 例如,要查看可执行文件test的大小信息,可以使用以下命令: ``` size test ``` 输出结果中,第一列为各个段的大小信息,第二列为段的名称,最后一列为文件名。 ### 回答2: size命令是用于查看目标文件或目标文件中函数和数据对象的大小的Linux命令。 这个命令用法非常简单,只需要在命令后面跟上目标文件的路径即可。当然,也可以同时指定多个目标文件,用空格分隔开即可。 size命令的输出结果通常会展示三个值,分别是text段(代码段)的大小、data段(数据段)的大小和bss段(未初始化数据段)的大小。这些值通常以十进制表示,但也可以通过size的选项进行控制。 通过size命令,我们可以了解目标文件的大小情况,这对于优化和调试程序非常有用。通过分析text段的大小,我们可以了解程序的代码长度,如果代码过长,可能需要进行一些优化措施以提高程序的执行效率。同样,通过分析data段和bss段的大小,我们可以了解目标文件中使用的全局变量和静态变量的大小情况,这对于程序的内存使用情况也非常有帮助。 总之,size命令是一个简单实用的Linux命令,可以帮助我们了解目标文件或可执行文件的大小情况,从而进行代码优化和程序调试。 ### 回答3: Size命令是一个用于统计目标文件或目录大小的Linux命令。它可以用来查看文件或目录占用的磁盘空间大小。 Size命令可以在终端中使用,语法如下: size [选项] [目标文件] 其中,选项可以是以下几种: - -A 或 --format=SysV: 以SysV格式显示文件大小。 - -B 或 --format=Berkeley: 以Berkeley格式显示文件大小。 - -H 或 --format=GNU: 以GNU format显示文件大小。 - -L 或 --format=SysV: 以SysV格式显示文件大小。 - -d 或 --decimal: 以十进制显示文件大小。 - -s 或 --total: 显示所有目标文件的总大小。 若不指定任何目标文件,则Size命令会显示当前目录下所有文件的大小。 Size命令会输出三个值:text、data和bss。这三个值分别表示可执行文件的代码段大小、数据段大小和空的BSS段(即在程序中声明但未进行初始化的全局变量占用的空间)大小。 除此之外,Size命令还会显示文件的总大小。有时候,我们需要查看某个文件夹下所有文件的总大小,可以使用Size命令的选项-s或--total。 总的来说,Size命令对于查看文件或目录大小是非常有用的。它可以帮助我们了解文件或目录占用的磁盘空间,方便我们进行存储管理和资源分配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值