如何访问C中.size指令设置的符号大小

时间:2019-01-08 02:08:27

标签: c assembly gnu

我已使用GNU汇编程序的.size指令设置了汇编中符号的大小,如何在C中访问此大小?

void my_func(void){}

asm(
    "_my_stub:\n\t"
    "call my_func\n\t"
    ".size _my_stub, .-_my_stub"
);

extern char* _my_stub;

int main(){
    /* print size of _my_stub here */
}

这里是相关的objdump

0000000000000007 <_my_stub>:
_my_stub():
   7:   e8 00 00 00 00          callq  c <main>

这是readelf的相关部分

Symbol table '.symtab' contains 14 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     5: 0000000000000007     5 NOTYPE  LOCAL  DEFAULT    1 _my_stub

我从objdump和symbol表中看到_my_stub的大小为5。如何在C中获得此值?

2 个答案:

答案 0 :(得分:2)

我不知道从gas中访问size属性的方法。或者,将.size替换为

hhh:
.long .-_my_stub     # 32-bit integer constant, regardless of the size of a C long

extern const uint32_t gfoo asm("hhh");
 // asm("asm_name") sidesteps the _name vs. name issue across OSes

我在这里无法尝试,但我希望您应该能够printf("%ld\n", gfoo);。我尝试使用.equ,所以这将是一个常量,而不是为其分配内存,但是我从来没有使其正常工作。

这确实就.size属性的用途提出了疑问。如果您看不懂为什么还要设置它?我不是专家,但是我有一个理论:

根据docs,对于COFF输出,.size必须在.def/.endef之内。查看.def,我们发现它用于开始为符号名称定义调试信息

尽管ELF没有相同的嵌套要求,但似乎也可以认为调试是有目的的。如果仅打算将其用于调试器,则它(kinda)表示没有办法从汇编器中访问它。

答案 1 :(得分:1)

我猜您只是想获取代码段或数据段的子集的大小。这是您可以参考的组装示例(GAS&AT样式):

target_start:
// Put your code segment or data segment here
// ...
target_end = .

// Use .global to export the label
.global target_size
target_size = target_end - target_start

在C / C ++源文件中,您可以使用target_size的标签extern long target_size

注意:此示例尚未经过测试。