問題
可執行文件通過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是未初始化的部分。