【发布时间】:2022-01-08 11:31:33
【问题描述】:
我正在尝试使用以下代码查找问题,需要知道链接器如何能够跟踪以下程序中的全局变量多重定义问题,我不太确定链接器如何在内部执行检查,因此请求帮助澄清。
**hello.h**
#ifndef __HELLO_
#define __HELLO_
static int s = 20;
int g = 10;
#endif
**cat hello1.c**
#include <stdio.h>
#include "hello.h"
//int g = 10;
int main()
{
g++;
s++;
printf("g : %d s : %d\n", g, s);
function();
return 0;
}
**cat hello2.c**
#include <stdio.h>
#include "hello.h"
//extern int g;
void function()
{
g++;
s++;
printf("g : %d s : %d\n", g, s);
}
**gcc -save-temps hello1.c hello2.c -o hello**
hello2.o:(.data+0x4): multiple definition of `g'
hello1.o:(.data+0x4): first defined here
**collect2: error: ld returned 1 exit status**
我不需要解决这个错误的解决方案,我知道上面的程序会像上面一样抛出 g 的多个定义错误,但是谁能解释一下 它是如何在链接阶段跟踪这个错误的?.
这是汇编代码的输出。
**cat hello1.s**
.file "hello1.c"
.data
.align 4
.type s, @object
.size s, 4
s:
.long 20
.globl g
.align 4
.type g, @object
.size g, 4
g:
.long 10
.section .rodata
.LC0:
.string "g : %d s : %d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl g(%rip), %eax
addl $1, %eax
movl %eax, g(%rip)
movl s(%rip), %eax
addl $1, %eax
movl %eax, s(%rip)
movl s(%rip), %edx
movl g(%rip), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
call function
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)"
.section .note.GNU-stack,"",@progbits
**cat hello2.s**
.file "hello2.c"
.data
.align 4
.type s, @object
.size s, 4
s:
.long 20
.globl g
.align 4
.type g, @object
.size g, 4
g:
.long 10
.section .rodata
.LC0:
.string "g : %d s : %d\n"
.text
.globl function
.type function, @function
function:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl g(%rip), %eax
addl $1, %eax
movl %eax, g(%rip)
movl s(%rip), %eax
addl $1, %eax
movl %eax, s(%rip)
movl s(%rip), %edx
movl g(%rip), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size function, .-function
.ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-44)"
.section .note.GNU-stack,"",@progbits
如果此查询之前已发布,请与我分享参考,无法跟踪类似链接。
【问题讨论】:
标签: c assembly x86 linker loader