问题
可执行文件通过size默认选项berkeley查询可以得到text、data、bss各个段的大小,但是想要通过.map分析代码或者哪些常量的具体大小时需要进一步知道更详细的数据。而通过size xxx–format=SysV 查到.text 和.rodata 仅占用一部分大小,而其他的section到底是属于berkeley模式中的哪类就需要通过分析size源码。
源码下载
dawn@ubuntu:~$ which size
/usr/bin/size
dawn@ubuntu:~$ dpkg -S /usr/bin/size
binutils: /usr/bin/size
dawn@ubuntu:~$
通过which和dpkg -S 组合确认命令size是在binutils包中。
具体下载、编译、安装binutils包的方法如下,我们其实只要下载到源码包那一步(步骤3)就行了。
1、在获取源码包之前,确保在软件源配置文件/etc/apt/sources.list中添加了deb-src项
2、使用如下命令获取源码包的详细信息:
sudo apt-cache showsrc binutils 这用来查询当前镜像站点中是否有该源码包。
3、源码包中通常包含3个文件,分别以dsc,orig.tar.gz和diff.gz为后缀名。
sudo apt-get source binutils 命令来获取源码包,它会将源码包下载到用户当前目录
并在命令执行过程中,调用dpkg-source命令,根据dsc文件中的信息,将源码包解压到同名目录中,应用程序的源代码就在这里面。
sudo apt-get source binutils
要强调的是,在下载源码包前,必须确保安装了dpkg-dev(执行”apt-get install dpkg-dev”来安装),
否则,只会下载源码包的3个文件,但不会解压缩源码包。当然你也可以自己用dpkg-source命令去解压缩源码包。
其实到这里已经有了源码包,我们只要解压后找到对应的命令行函数就行了。
至于后面如果有需要修改、编译、安装的话再用下面的步骤
4、在编译源码包前,需要安装具有依赖关系的相关软件包。使用”apt-get build-dep”命令可以主动获取并安装所有相关的软件包。
sudo apt-get build-dep binutils
5、现在可以来编译源码包了,首先进入源码所在目录,使用dpkg-buildpackage命令来编译源码包,它会将生成的Deb软件包放置在上层目录中。
cd binutils
sudo dpkg-buildpackage
这样就会编译生成xxx.deb
6、安装软件包。使用”dpkg –i”命令来安装生成的Deb软件包。
sudo dpkg -i xxx.deb
源码分析
通过查看size命令源码有如下逻辑:
if ((flags & SEC_CODE) != 0 || (flags & SEC_READONLY) != 0)
textsize += size;
else if ((flags & SEC_HAS_CONTENTS) != 0)
datasize += size;
else
bsssize += size;
也就是text字段size是section 中flag里有表示code(可执行)或者只读属性的section的大小之和。
通过readelf –S 查看section headers关注Flags字段属性,如下图标注字段和最后flag含义:
可以知道不带“W”的即为只读属性,带“X”为可执行code属性
那么把拥有上述属性(不包括空属性和MS)的section size求和,从而得到text大小为上述section size 之和。
同理通过size命令的逻辑可以知道,有可写属性“W”的data和bss 区别是data是有内容,也就是bss是未初始化的部分。