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格式

size命令的sysv和berkeley格式差别的更多相关文章

  1. 在Linux命令行下发送html格式的邮件

    在Linux利用formail+sendmail来发送带图片的邮件 formail接收html格式的文件作为邮件的内容,这样就可以解决发送带图片邮件的问题了,因为html中可以插入图片,只要给出的im ...

  2. 【转载】Oracle sqlplus中最简单的一些命令,设置显示的格式

    登录数据库: 方式(1)当我们刚安装Oracle数据库时,登录账户时可以使用win+r 输入sqlplus,进入sqlplus命令窗口,然后输入用户名和密码,这里输入密码时不会有回显 方式(2)使用w ...

  3. 修改linux系统history命令的条数和格式

    在一次测试环境遇到的情况,发现服务莫名其妙挂了,以为服务有bug,查了一下午,后来一个同事说,是我把服务关了啊.... 是可忍孰不可忍,原生的history命令,只能看到输入的命令历史,看不到什么时候 ...

  4. Atitit.jpg png格式差别以及解决jpg图片不显示的问题

    Atitit.模板引擎原理以及常见模板技术 1. Asp Php jsp smarty模板1 1.1. 模板引擎基本原理1 1.2. 调试模式原理2 2. Attilax总结的模板引擎原理2 3. 支 ...

  5. 解读Linux命令格式(转)

    解读Linux命令格式   环境 Linux HA5-139JK 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x8 ...

  6. FTP命令 - Size的问题

    今天发现一个服务从某一个外接系统(Linux)FTP取到的文件大小和下载后的文件大小总是不一致. 开始以为是程序那里出错了.但是找来找去发现不了原因.后来用FTP工具上去执行SIZE命令,终于发现返回 ...

  7. Crontab命令格式

    第1列分钟1-59第2列小时1-23(0表示子夜)第3列日1-31第4列月1-12第5列星期0-6(0表示星期天)第6列要运行的命令 下面是crontab的格式: 分 时 日 月 星期 要运行的命令 ...

  8. linux常用命令 print格式输出

    格式化输出命令 printf '输出类型 输出格式' 输出内容 输出类型: %ns 输出字符串,n是数字指代输出的几个字符 %ni 输出整数,n是数字指代输出几个数字 %m.nf 输出浮点数.m和n是 ...

  9. crontab格式,命令

    http://www.blogjava.net/xiaomage234/archive/2007/12/26/170490.html crontab格式: 第1列分钟1-59 第2列小时1-23(0表 ...

随机推荐

  1. 学习11:内容# 1.函数名第一类对象及使用 ***** # 2.f格式化 *** # 3.迭代器 **** # 4.递归 ****

    目录 1.第一类对象 -- 特殊点 2.f.格式化 Python3.6版本以上才能够使用 3.迭代器 迭代 : 器 : 工具 4.递归 1.第一类对象 -- 特殊点 1.可以当做值被赋值给变量 def ...

  2. [记录]python使用serial模块实现实时WebConsole

    ###tornado+websocket+多进程实现: 1.index.html <!DOCTYPE HTML> <html> <head> <style&g ...

  3. 个人永久性免费-Excel催化剂功能第52波-相同内容批量合并单元格,取消合并单元格并填充内容

    在高级Excel用户群体中无比痛恨的合并单元格,在现实的表格中却阴魂不散的纠缠不断.今天Excel催化剂也来成为“帮凶”,制造更多的合并单元格.虽然开发出此功能,请使用过程中务必要保持节制,在可以称为 ...

  4. David与Vincent的博弈游戏[树型DP]

    \(\mathcal{Description}\) \(\mathcal{Solution}\) 根据题意,我们知道 根节点深度为1,深度为 奇数 的节点由\(David\)移动,我们称为\(D\)点 ...

  5. FJNUOJ 1002 画葫芦。。

    画图就是..找..规..律 #include <iostream>using namespace std;int main(){ int T; cin>>T; while(T- ...

  6. [leetcode] 621. Task Scheduler(medium)

    原题 思路: 按频率最大的字母来分块,频率最大的字母个数-1为分成的块数,每一块个数为n+1 比如AAABBCE,n=2, 则分为A-A- +A AAABBBCCEE,n=2,则分为AB-AB- +A ...

  7. Flutter学习笔记(10)--容器组件、图片组件

    如需转载,请注明出处:Flutter学习笔记(10)--容器组件.图片组件 上一篇Flutter学习笔记(9)--组件Widget我们说到了在Flutter中一个非常重要的理念"一切皆为组件 ...

  8. 【MySQL】(七)事务

    我的个人博客 http://www.haxianhe.com/ 数据库系统引入事务的主要目的:事务会把数据库从一种状态转换为另一种一致状态.在数据库提交工作时,可以确保要么所有修改都已经保存了,要么所 ...

  9. python初步编写用户登录

     python初步编写用户登录 python编写用户登录 用python写一个脚本,使得这个脚本在执行后,可以产生如下的效果: 1.用户的账号为:root 密码为:westos 2.用户账号和密码均输 ...

  10. IntegerCache的妙用和陷阱

    转载自IntegerCache的妙用和陷阱 考虑下面的小程序,你认为会输出为什么结果? public class Test {     public static void main(String[] ...