【发布时间】:2017-01-14 15:06:17
【问题描述】:
在分析编译为 ARM 平台的 ELF 文件的 C++ 程序的 .bss 部分时,我遇到了几种确定大小的方法。问题Tool to analyze size of ELF sections and symbol中也提到了我测试的四种方式。
然而,结果却大不相同:
bss size according to nm: 35380
bss size according to readelf: 37632
bss size according to size: 37888
bss size according to objdump: 37594
这可能是什么原因?
用于生成输出的 Python 脚本
#!/usr/bin/env python
import re
import subprocess
import sys
fname = sys.argv[1]
# nm
output = subprocess.check_output(['arm-none-eabi-nm','-l','-S','-C',fname])
size = 0
for line in output.splitlines():
m = re.search('[0-9a-f]* ([0-9a-f]*) ([a-zA-Z]) ([^/]*)\s*([^\s]*)',line)
if m:
stype = m.group(2).strip()
if stype in ['B','b']:
size += int(m.group(1),16)
print "bss size according to nm: \t%i" % size
# readelf
output = subprocess.check_output(['arm-none-eabi-readelf','-S',fname])
for line in output.splitlines():
m = re.search('bss\s+[A-Z]+\s+[0-9a-f]+ [0-9a-f]+ ([0-9a-f]+)',line)
if m:
print "bss size according to readelf: \t%i" % int(m.group(1),16)
break
# size
output = subprocess.check_output(['arm-none-eabi-size',fname])
for line in output.splitlines():
m = re.search('[0-9]+\s+[0-9]+\s+([0-9]+)',line)
if m:
print "bss size according to size: \t%i" % int(m.group(1))
break
# objdump
output = subprocess.check_output(['arm-none-eabi-objdump','-C','-t','-j','.bss',fname])
size = 0
for line in output.splitlines():
m = re.search('bss\s+([0-9a-f]*)\s+',line)
if m:
size += int(m.group(1),16)
print "bss size according to objdump: \t%i" % size
编辑:我发现的一件事是 nm 将函数内部的静态变量(正确)分类为弱 (V),尽管它们可能是 .bss 的一部分。但是,并非所有归类为 V 的部分都是 .bss 的一部分,因此我不能只将所有 V 部分添加到大小中。那么这个任务用 nm 是不可能的吗?
【问题讨论】:
-
你试过
llvm-nm,它与 LLVM/clang 捆绑在一起吗?也许它不会同意nm在这方面 -
您是测试对象文件 (
ET_REL) 还是完全链接的对象(ET_EXEC和ET_DYN)?为什么您期望将单个符号大小相加会得出正确的数字? -
@valiano 不,
llvm-nm给出相同的结果。 -
@FlorianWeimer 这是一个 ET_EXEC。回答为什么总结各个符号大小会导致可能不正确的结果将是答案的一部分。
标签: gcc arm objdump nm readelf