我正面临着联系问题。我将说明一下:
交流转换器:
extern void b(void);
int main() {
a();
return 0;
}
void a() {
b();
}
b.S:
.extern a
b:
jmp a
无论我是否链接
gcc a.o b.o -o c
或
gcc b.o a.o -o c
我会得到未解决的符号。如何链接这些文件?我无法合并它们。示例可能是荒谬的,但这说明了一点,我尝试归档什么。
答案 0 :(得分:3)
初步调查:
<强>交流转换器强>
extern void b(void);
void a(void);
int main() {
a();
return 0;
}
void a() {
b();
}
<强> b.S 强>
.extern a
b:
jmp a
<强> b.c 强>
void a(void);
void b(void)
{
a();
}
<强>输出强>
$ gcc -c a.c
$ gcc -c b.c -o b_gcc.o
$ as b.S -o b_as.o
$ gcc a.o b_gcc.o -o test_gcc
$ gcc a.o b_as.o -o test_as
a.o: In function `a':
a.c:(.text+0x15): undefined reference to `b'
collect2: error: ld returned 1 exit status
那是什么给出的?为什么GCC可以,但不是GAS?
$ objdump -t b_gcc.o > syms_gcc
$ objdump -t b_as.o > syms_as
$ diff syms_gcc syms_as
2c2
< b_gcc.o: file format elf64-x86-64
---
> b_as.o: file format elf64-x86-64
5d4
< 0000000000000000 l df *ABS* 0000000000000000 b.c
9,12c8
< 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
< 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
< 0000000000000000 l d .comment 0000000000000000 .comment
< 0000000000000000 g F .text 000000000000000b b
---
> 0000000000000000 l .text 0000000000000000 b
好的,gcc
使b
成为全局符号。让我们在.global b
中尝试b.S
:
$ as b.S -o b_as2.o
$ gcc a.o b_as2.o
$
成功。因此gcc
/ ld
将对不在静态库中的任何内容执行多遍符号解析。但它只有寻找全局符号。这是最后的b.S
:
.extern a
.global b
b:
jmp a