【问题标题】:Objdump disassemble doesn't match source codeObjdump 反汇编与源代码不匹配
【发布时间】:2017-10-17 22:39:06
【问题描述】:

我正在研究链接到 libgomp 的 OpenMP 程序的执行流程。它使用#pragma omp parallel for。我已经知道这个结构变成了对GOMP_parallel 函数的调用,具体实现如下:

void
GOMP_parallel (void (*fn) (void *), void *data, 
               unsigned num_threads, unsigned int flags)
{
   num_threads = gomp_resolve_num_threads (num_threads, 0);
   gomp_team_start (fn, data, num_threads, flags, gomp_new_team (num_threads));
   fn (data);
   ialias_call (GOMP_parallel_end) ();
}

在 libgomp 上执行objdump -d 时,GOMP_parallel 显示为:

000000000000bc80 <GOMP_parallel@@GOMP_4.0>:
bc80:   41 55                   push   %r13
bc82:   41 54                   push   %r12
bc84:   41 89 cd                mov    %ecx,%r13d
bc87:   55                      push   %rbp
bc88:   53                      push   %rbx
bc89:   48 89 f5                mov    %rsi,%rbp
bc8c:   48 89 fb                mov    %rdi,%rbx
bc8f:   31 f6                   xor    %esi,%esi
bc91:   89 d7                   mov    %edx,%edi
bc93:   48 83 ec 08             sub    $0x8,%rsp
bc97:   e8 d4 fd ff ff          callq  ba70 <GOMP_ordered_end@@GOMP_1.0+0x70>
bc9c:   41 89 c4                mov    %eax,%r12d
bc9f:   89 c7                   mov    %eax,%edi
bca1:   e8 ca 37 00 00          callq  f470 <omp_in_final@@OMP_3.1+0x2c0>
bca6:   44 89 e9                mov    %r13d,%ecx
bca9:   44 89 e2                mov    %r12d,%edx
bcac:   48 89 ee                mov    %rbp,%rsi
bcaf:   48 89 df                mov    %rbx,%rdi
bcb2:   49 89 c0                mov    %rax,%r8
bcb5:   e8 16 39 00 00          callq  f5d0 <omp_in_final@@OMP_3.1+0x420>
bcba:   48 89 ef                mov    %rbp,%rdi
bcbd:   ff d3                   callq  *%rbx
bcbf:   48 83 c4 08             add    $0x8,%rsp
bcc3:   5b                      pop    %rbx
bcc4:   5d                      pop    %rbp
bcc5:   41 5c                   pop    %r12
bcc7:   41 5d                   pop    %r13
bcc9:   e9 32 ff ff ff          jmpq   bc00 <GOMP_parallel_end@@GOMP_1.0>
bcce:   66 90                   xchg   %ax,%ax

首先,例如GOMP_parallel 的源代码中没有对GOMP_ordered_end 的任何调用。其次,该功能包括:

void
GOMP_ordered_end (void)
{
}

根据 objdump 输出,此函数从 ba00 开始并在 bbbd 结束。一个空的函数里怎么会有这么多代码?顺便说一句,libgomp的源代码中有注释说它应该只在使用ORDERED构造时出现(顾名思义),我的测试不是这样。

最后,我主要关心的是:为什么源代码与反汇编有这么大的不同?例如,为什么在程序集中没有提及gomp_team_start

系统有gcc 5.4.0版

【问题讨论】:

  • gcc 内联小函数。其中一些“函数”甚至可能是 CPP 宏。
  • 您的objdump -d 输出中没有对GOMP_ordered_end 的调用。取而代之的是对GOMP_ordered_end@@GOMP_1.0+0x70 的调用,这是一个未命名的函数,位于GOMP_ordered_end@@GOMP_1.0 开始之后的0x70 字节处。
  • 如果你真的怀疑编译后的代码和源代码不一样,那么第一步就是看一下C宏展开后的代码(gcc -E)。下一步是查看生成的汇编代码(gcc -S)。

标签: gcc assembly compilation objdump libgomp


【解决方案1】:

根据 objdump 的输出,这个函数从 ba00 开始,在 bbbd 结束。 一个空的函数怎么会有这么多代码?

函数本身很小,但 GCC 只是使用了一些额外的字节来对齐下一个函数并存储一些静态数据(可能被此文件中的其他函数使用)。这是我在本地ordered.o看到的:

00000000000003b0 <GOMP_ordered_end>:
 3b0:   f3 c3                   repz retq
 3b2:   66 66 66 66 66 2e 0f    data32 data32 data32 data32 nopw %cs:0x0(%rax,%rax,1)
 3b9:   1f 84 00 00 00 00 00

首先,例如,在 GOMP_parallel 的源代码中没有对 GOMP_ordered_end 的任何调用。

不要被汇编代码中的GOMP_ordered_end@@GOMP_1.0+0x70 标记分心。它只是说这调用了一些本地库函数(objdump 没有找到任何符号信息),它恰好位于GOMP_ordered_end 之后的 112 个字节处。这很可能是gomp_resolve_num_threads

例如,为什么在程序集中没有提及 gomp_team_start?

嗯,这看起来很像:

bcb5:   e8 16 39 00 00          callq  f5d0 <omp_in_final@@OMP_3.1+0x420>

【讨论】:

  • 对齐不足以解释空函数的 0xbd 字节。一定是发生了其他事情。
  • @yugr 我的意思是“GOMP_ordered_end”。我想说的是:“GOMP_ordered_end”是如何出现在“GOMP_parallel”的反汇编中的,但源代码中没有对该函数的任何调用?
  • @PeterCordes 是的,但这不是问题的核心,所以我没有费心去检查......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
相关资源
最近更新 更多