Disassembly file: objdump
objdump file¶
Disassembly of section .plt:
0000000000402020 <.plt>:
402020: ff 35 e2 bf 02 00 pushq 0x2bfe2(%rip) # 42e008 <_GLOBAL_OFFSET_TABLE_+0x8>
402026: ff 25 e4 bf 02 00 jmpq *0x2bfe4(%rip) # 42e010 <_GLOBAL_OFFSET_TABLE_+0x10>
40202c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000402030 <_Znam@plt>:
402030: ff 25 e2 bf 02 00 jmpq *0x2bfe2(%rip) # 42e018 <_Znam@GLIBCXX_3.4>
402036: 68 00 00 00 00 pushq $0x0
40203b: e9 e0 ff ff ff jmpq 402020 <.plt>
0000000000402040 <_ZNSo3putEc@plt>:
402040: ff 25 da bf 02 00 jmpq *0x2bfda(%rip) # 42e020 <_ZNSo3putEc@GLIBCXX_3.4>
402046: 68 01 00 00 00 pushq $0x1
40204b: e9 d0 ff ff ff jmpq 402020 <.plt>
.plt
节主要实现了使用过程链接表(Procedure Linkage Table)实现延迟绑定的功能。
openmp相关的执行¶
omp_outlined函数¶
问题:objdump 程序 有许多 类似 <.omp_outlined..16>: 的函数,但是main函数里并没有调用。实际openmp是怎么执行这些代码的呢?
在使用了OpenMP指令的C/C++程序编译后,编译器会自动生成一些名为.omp_outlined.
的函数。这些函数是OpenMP所需要的运行时支持函数,不是直接在main函数中调用的,其执行方式主要有以下几种:
- 一些关键的运行时函数,如线程创建、同步等,是在程序启动时由OpenMP运行时库初始化和直接调用的。
- 对于并行region,编译器会在主线程发起并行时调用对应的
.omp_outlined.
函数创建线程并发布工作。 - 一些工作分配,同步等调用也是隐式通过运行时库的支持函数实现的。
- 对于并行循环,编译器会将循环体移动到
.omp_outlined.
函数,在循环分配工作时调用。 - 减少指令,作用域变化等也会引发这些函数的调用。
所以.omp_outlined.
函数的执行是隐式通过运行时库触发和调度的,不需要用户代码直接调用。它们是OpenMP实现所必须的,由编译器和运行时库协调完成。用户只需要编写OpenMP指令,不必关心具体的调用细节。
总体来说,这是一种让并行执行透明化的实现机制,减少了用户的工作量。
OpenMP的汇编代码¶
不同平台不同,有GOMP_parallel_start开头的。也有如下x86平台的
405854: 48 c7 84 24 a0 00 00 movq $0x4293b9,0xa0(%rsp)
40585b: 00 b9 93 42 00
405860: 48 8d bc 24 90 00 00 lea 0x90(%rsp),%rdi
405867: 00
405868: ba 10 5f 40 00 mov $0x405f10,%edx
40586d: be 02 00 00 00 mov $0x2,%esi
405872: 4c 89 f9 mov %r15,%rcx
405875: 4c 8b 44 24 20 mov 0x20(%rsp),%r8
40587a: 31 c0 xor %eax,%eax
40587c: e8 ff cb ff ff callq 402480 <__kmpc_fork_call@plt>
405881: 48 8b 7c 24 60 mov 0x60(%rsp),%rdi
这段汇编代码实现了OpenMP中的并行构造,主要执行了以下几个步骤:
- 在栈上写入一个常量0x4293b9,可能是team的参数 (48 c7 84 24)
- 准备参数,获取rsp+0x90地址到rdi作为第1参数 (%rdi)
- 设置edx为0x405f10,可能是kmp_routine函数地址
- esi设置为2,可能表示有2个参数
- r15设置到rcx,传入线程号参数
- r8传入栈上第0x20个参数,可能是void* shareds参数
- 清空eax,一些调用约定使用
- 调用
__kmpc_fork_call
函数,这是OpenMP的runtime库函数,用来并行执行一个函数 kmpc
fork multiple parallel call?- 最后将返回值保存在rdi指定的栈空间上
所以这段代码实现了调用OpenMP runtime并行执行一个函数的操作,准备参数,调用runtime API,获取返回值的一个流程。
利用runtime库的支持函数可以实现汇编级别的OpenMP并行性。
readelf¶
各section位置以及含义,参考文档
$ readelf -S bfs.inj
There are 37 section headers, starting at offset 0xbe8e8:
在文件内 0xbe8e8字节开始
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
序号 节名称 节类型 节的虚拟地址偏移量 节在文件中的偏移量
节大小 每个条目的大小(如果大小固定) 节的标志 节的链接信息 节的额外信息 节的信息对齐方式
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 00000000004002a8 000002a8
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.gnu.build-i NOTE 00000000004002c4 000002c4
0000000000000024 0000000000000000 A 0 0 4
[ 3] .note.ABI-tag NOTE 00000000004002e8 000002e8
0000000000000020 0000000000000000 A 0 0 4
[ 4] .gnu.hash GNU_HASH 0000000000400308 00000308
000000000000005c 0000000000000000 A 5 0 8
[ 5] .dynsym DYNSYM 0000000000400368 00000368
00000000000007e0 0000000000000018 A 6 1 8
[ 6] .dynstr STRTAB 0000000000400b48 00000b48
0000000000000b1d 0000000000000000 A 0 0 1
[ 7] .gnu.version VERSYM 0000000000401666 00001666
00000000000000a8 0000000000000002 A 5 0 2
[ 8] .gnu.version_r VERNEED 0000000000401710 00001710
0000000000000110 0000000000000000 A 6 5 8
[ 9] .rela.dyn RELA 0000000000401820 00001820
00000000000000f0 0000000000000018 A 5 0 8
[10] .rela.plt RELA 0000000000401910 00001910
00000000000006c0 0000000000000018 AI 5 24 8
[11] .init PROGBITS 0000000000402000 00002000
000000000000001b 0000000000000000 AX 0 0 4
[12] .plt PROGBITS 0000000000402020 00002020
0000000000000490 0000000000000010 AX 0 0 16
[13] .text PROGBITS 00000000004024b0 000024b0
0000000000026475 0000000000000000 AX 0 0 16
[14] .fini PROGBITS 0000000000428928 00028928
000000000000000d 0000000000000000 AX 0 0 4
[15] .rodata PROGBITS 0000000000429000 00029000
0000000000001180 0000000000000000 A 0 0 16
[16] .eh_frame_hdr PROGBITS 000000000042a180 0002a180
00000000000002ac 0000000000000000 A 0 0 4
[17] .eh_frame PROGBITS 000000000042a430 0002a430
0000000000001780 0000000000000000 A 0 0 8
[18] .gcc_except_table PROGBITS 000000000042bbb0 0002bbb0
00000000000005d0 0000000000000000 A 0 0 4
[19] .init_array INIT_ARRAY 000000000042dbc8 0002cbc8
0000000000000010 0000000000000008 WA 0 0 8
[20] .fini_array FINI_ARRAY 000000000042dbd8 0002cbd8
0000000000000008 0000000000000008 WA 0 0 8
[21] .data.rel.ro PROGBITS 000000000042dbe0 0002cbe0
00000000000001f0 0000000000000000 WA 0 0 8
[22] .dynamic DYNAMIC 000000000042ddd0 0002cdd0
0000000000000220 0000000000000010 WA 6 0 8
[23] .got PROGBITS 000000000042dff0 0002cff0
0000000000000010 0000000000000008 WA 0 0 8
[24] .got.plt PROGBITS 000000000042e000 0002d000
0000000000000258 0000000000000008 WA 0 0 8
[25] .data PROGBITS 000000000042e258 0002d258
0000000000000010 0000000000000000 WA 0 0 8
[26] .bss NOBITS 000000000042e280 0002d268
0000000000000180 0000000000000000 WA 0 0 64
[27] .comment PROGBITS 0000000000000000 0002d268
000000000000004a 0000000000000001 MS 0 0 1
[28] .debug_info PROGBITS 0000000000000000 0002d2b2
000000000002a06e 0000000000000000 0 0 1
[29] .debug_abbrev PROGBITS 0000000000000000 00057320
0000000000000a57 0000000000000000 0 0 1
[30] .debug_line PROGBITS 0000000000000000 00057d77
000000000000af9a 0000000000000000 0 0 1
[31] .debug_str PROGBITS 0000000000000000 00062d11
0000000000010328 0000000000000001 MS 0 0 1
[32] .debug_loc PROGBITS 0000000000000000 00073039
0000000000042846 0000000000000000 0 0 1
[33] .debug_ranges PROGBITS 0000000000000000 000b587f
00000000000054c0 0000000000000000 0 0 1
[34] .symtab SYMTAB 0000000000000000 000bad40
00000000000018c0 0000000000000018 35 106 8
[35] .strtab STRTAB 0000000000000000 000bc600
0000000000002177 0000000000000000 0 0 1
[36] .shstrtab STRTAB 0000000000000000 000be777
000000000000016c 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
字段含义¶
- Type 字段,具体含义参考文档1-10
- Link 字段中的值是节头表中节头条目的索引,索引从0开始,表示第一个节头表条目,依此类推。比如5 代表与
[ 5] .dynsym
有关
值得注意¶
One section type, SHT_NOBITS
described below, occupies no
space in the file, and its sh_offset
member locates the conceptual placement in the
file.
so the number "2d258" remains unchanged.
[25] .data PROGBITS 000000000042e258 0002d258
0000000000000010 0000000000000000 WA 0 0 8
[26] .bss NOBITS 000000000042e280 0002d268
0000000000000180 0000000000000000 WA 0 0 64
.got¶
global offset table
.plt¶
This section holds the procedure linkage table. See ‘‘Special Sections’’ in Part 1 and ‘‘Procedure Linkage Table’’ in Part 2 for more information.
Function symbols (those with type STT_FUNC) in shared object files have special significance. When another object file references a function from a shared object, the link editor automatically creates a procedure linkage table entry for the referenced symbol.
需要进一步的研究学习¶
暂无
遇到的问题¶
暂无
开题缘由、总结、反思、吐槽~~¶
参考文献¶
上面回答部分来自ChatGPT-3.5,没有进行正确性的交叉校验。
无