对象链接顺序问题

时间:2017-12-10 19:10:22

标签: c gcc

我正面临着联系问题。我将说明一下:

交流转换器:

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

我会得到未解决的符号。如何链接这些文件?我无法合并它们。示例可能是荒谬的,但这说明了一点,我尝试归档什么。

1 个答案:

答案 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
相关问题