assembly 使用了什么IO标准输入

jum4pzuy  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(72)

有人能解释一下下面一行中的_IO_stdin_used是什么吗?

114a:   48 8d 3d b3 0e 00 00    lea    rdi,[rip+0xeb3]        # 2004 <_IO_stdin_used+0x4>

抱歉问了个菜鸟问题。

bis0qfac

bis0qfac1#

扩展https://stackoverflow.com/users/224132/peter-cordes的注解(What is_IO_stdin_used),一些工具可以帮助理解这一点。

#include <stdio.h>
void main (void) {
  puts("hello!");
}

是这样建造的:LDFLAGS=-Wl,-Map=burt.map make burt
我们稍后将查看Map文件,首先检查可执行文件:

$ objdump -xsd -M intel burt
...
0000000000002000 g     O .rodata        0000000000000004              _IO_stdin_used
...
Contents of section .rodata:
 2000 01000200 68656c6c 6f2100             ....hello!.
...
    1148:       48 8d 05 b5 0e 00 00    lea    rax,[rip+0xeb5]        # 2004 <_IO_stdin_used+0x4>
    114f:       48 89 c7                mov    rdi,rax
    1152:       e8 d9 fe ff ff          call   1030 <puts@plt>
...

注意,字符串的位置(2004h)在符号表中没有条目(2000h条目_IO_stdin_used出现的地方),所以objdump的反汇编注解相对于它知道的另一个符号提到了它。
但是为什么它知道_IO_stdin_used,或者,为什么包含这个符号,为什么它有一个名称?burt.map显示它来自Scrt1.o

...
.rodata         0x0000000000002000        0xb
 *(.rodata .rodata.* .gnu.linkonce.r.*)
 .rodata.cst4   0x0000000000002000        0x4 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/../../../../lib/Scrt1.o
 .rodata        0x0000000000002004        0x7 /tmp/ccYG1XvK.o
...

在我的电脑上,Scrt1.o属于glibc,符号可以追溯到这里:https://sourceware.org/git/?p=glibc.git;a=blob;f=csu/init.c;h=c2f978f3da565590bcab355fefa3d81cf211cb36;hb=63fb8f9aa9d19f85599afe4b849b567aefd70a36.
为了证明由于地址没有名字而在objdump反汇编中显示,我们可以给字符串一个名字,将其添加到符号表中,这样objdump就会显示它。

#include <stdio.h>
const char greeting[] = "hello!";
void main (void) {
  puts(greeting);
}

构建,然后检查:

...
0000000000002004 g     O .rodata        0000000000000007              greeting
...
0000000000002000 g     O .rodata        0000000000000004              _IO_stdin_used
...
Contents of section .rodata:                                                                     
 2000 01000200 68656c6c 6f2100             ....hello!.
...
    113d:       48 8d 05 c0 0e 00 00    lea    rax,[rip+0xec0]        # 2004 <greeting>
    1144:       48 89 c7                mov    rdi,rax
    1147:       e8 e4 fe ff ff          call   1030 <puts@plt>

相对于rip的偏移量发生了一些变化,因为.text.rodata部分现在稍微分开了一些,尽管.rodata的内容保持不变,因为选择源代码修改是为了避免修改.rodata--如果greetings不是const,它将位于.data中。下面的Map文件现在显示了burt.c的临时对象文件对.rodata的贡献,定义了greeting符号,与之前的Map文件相比,相同的数据没有名称:

.rodata         0x0000000000002000        0xb                                                    
 *(.rodata .rodata.* .gnu.linkonce.r.*)                                                          
 .rodata.cst4   0x0000000000002000        0x4 /usr/lib/gcc/x86_64-pc-linux-gnu/12.2.1/../../../..
/lib/Scrt1.o
                0x0000000000002000                _IO_stdin_used
 .rodata        0x0000000000002004        0x7 /tmp/ccDnWXjG.o
                0x0000000000002004                greeting

相关问题