2017-10-17 320 views
2

我正在调查与libgomp链接的OpenMP程序的执行流程。它使用#pragma omp parallel for。我已经知道该构建而成,除其他事项外,调用GOMP_parallel功能,这是实现如下:Objdump反汇编不匹配源代码

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 -dGOMP_parallel显示为:

000000000000bc80 <[email protected]@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 <[email protected]@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 <[email protected]@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 <[email protected]@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 <[email protected]@GOMP_1.0> 
bcce: 66 90     xchg %ax,%ax 

首先,例如,在GOMP_parallel的源代码中没有任何呼叫GOMP_ordered_end。其次,功能包括:

void 
GOMP_ordered_end (void) 
{ 
} 

根据该objdump的输出,该功能开始于ba00bbbd结束。它如何在一个空的函数中有这么多的代码?顺便说一句,在libgomp的源代码中有评论说只有在使用ORDERED构造(顾名思义)时才会出现,这不是我测试的情况。

最后,我主要关心的是:为什么源代码与反汇编差异很大?例如,为什么在组件中没有提到gomp_team_start

该系统具有gcc版本5.4.0

+1

GCC内联小函数。其中一些“功能”甚至可能是CPP宏。 –

+3

在你的'objdump -d'输出中没有对'GOMP_ordered_end'的调用。而是调用'GOMP_ordered_end @@ GOMP_1.0 + 0x70',这是一个未命名的函数,它位于'GOMP_ordered_end @@ GOMP_1.0'开始后的0x70个字节处。 –

+0

如果您确实怀疑编译后的代码与源代码不同,那么首先要看看C宏扩展('gcc -E')后的代码。下一步是查看生成的汇编代码('gcc -S')。 – dirkt

回答

3

根据该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任何呼叫,例如。

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

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

嗯,这看起来很像是:

​​
+0

对齐不足以解释空函数的0xbd字节。还有其他一些事情正在发生。 –

+0

@yugr我的意思是“GOMP_ordered_end”。我想说的是:“GOMP_ordered_end”是如何在“GOMP_parallel”的反汇编中出现的,但是在源代码中没有任何对那个函数的调用? –

+0

@MárcioJales明白了,我更新了答案。 – yugr