Mac OS X 上的弱符号链接

发布于 2024-11-07 16:30:00 字数 2897 浏览 0 评论 0原文

目前,我在使用 Xcode 4.0.2 的 Mac OS X 10.6.7 上遇到了弱链接问题。

$ gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)

正如开发人员文档所述,我们可以使用 gcc <弱链接符号的strong>属性((weak_import))。但是,以下示例代码总是抛出编译错误。
如下:

weak.c

#include <stdlib.h>
#include <stdio.h>

extern int SayHello() __attribute__((weak));

int main()
{
    int result;

    if (SayHello!=NULL)
    {
        printf("SayHello is present!\n");
        result=SayHello();
    }
    else
        printf("SayHello is not present!\n");
}

错误信息如下:

$ gcc weak.c 
Undefined symbols for architecture x86_64:
  "_f", referenced from:
      _main in cceOf2wN.o
     (maybe you meant: __dyld_func_lookup)
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

即使使用选项-undefinedynamic_lookup,它仍然在运行时抛出错误:

$ gcc -undefined dynamic_lookup weak.c 
$ ./a.out 
dyld: Symbol not found: _SayHello
  Referenced from: /private/tmp/o/./a.out
  Expected in: dynamic lookup

Trace/BPT trap

nm - “a.out”的 m 消息如下:

$ nm -m a.out  | grep Hello

(undefined) external _SayHello (dynamically looked up)

预期如下:

(undefined) weak external _SayHello (dynamically looked up)

但是,当我使用 gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 在 Ubuntu 上编译时,它按预期工作:

weak.c:

#include <stdlib.h>
#include <stdio.h>

extern int SayHello() __attribute__((weak));

int main()
{
    int result;

    if (SayHello!=NULL)
    {
        printf("SayHello is present!\n");
        result=SayHello();
    }
    else
        printf("SayHello is not present!\n");
}

 

$ gcc weak.c 
$ ./a.out 
SayHello is not present!

SayHello 的二进制符号为:

$ nm a.out | grep Hello
w SayHello

“w”符号是弱符号,尚未被专门标记为弱对象符号。

我测试了旧的 xcode 3.2,它按预期工作。

有人能帮我解决这个问题吗?难道是ld的bug?

我发现了更多有趣的事情。当我创建一个虚拟库来导出动态库中的 SayHello 符号时,它按预期工作。

dummy.c

int SayHello() {
    return;
}

$ gcc -dynamiclib -o libdummy.dylib dummy.c 
$ gcc weak.c libdummy.dylib 
$ ./a.out 
SayHello is present!

如果“libdummy.dylib”不存在:

$ rm libdummy.dylib 
$ ./a.out 
SayHello is not present!

按预期工作!正如预期的那样,nm 消息中现在有弱符号:

$ nm -m a.out | grep Hello

                 (undefined) weak external _SayHello (from libdummy)

Currently I encountered a weak link issue on Mac OS X 10.6.7 with Xcode 4.0.2.

$ gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)

As the developer document said, we can use gcc attribute((weak_import)) for weak link symbol. However, the following sample code always throw compile error.
As the following:

weak.c:

#include <stdlib.h>
#include <stdio.h>

extern int SayHello() __attribute__((weak));

int main()
{
    int result;

    if (SayHello!=NULL)
    {
        printf("SayHello is present!\n");
        result=SayHello();
    }
    else
        printf("SayHello is not present!\n");
}

The error message is the following:

$ gcc weak.c 
Undefined symbols for architecture x86_64:
  "_f", referenced from:
      _main in cceOf2wN.o
     (maybe you meant: __dyld_func_lookup)
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status

Even if use option -undefined dynamic_lookup, it still throws error at runtime:

$ gcc -undefined dynamic_lookup weak.c 
$ ./a.out 
dyld: Symbol not found: _SayHello
  Referenced from: /private/tmp/o/./a.out
  Expected in: dynamic lookup

Trace/BPT trap

The nm -m message of "a.out" is the following:

$ nm -m a.out  | grep Hello

(undefined) external _SayHello (dynamically looked up)

Which was expected as the following:

(undefined) weak external _SayHello (dynamically looked up)

However, when I compile on Ubuntu with gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5, it works as expected:

weak.c:

#include <stdlib.h>
#include <stdio.h>

extern int SayHello() __attribute__((weak));

int main()
{
    int result;

    if (SayHello!=NULL)
    {
        printf("SayHello is present!\n");
        result=SayHello();
    }
    else
        printf("SayHello is not present!\n");
}

$ gcc weak.c 
$ ./a.out 
SayHello is not present!

The symbol of SayHello in binary is:

$ nm a.out | grep Hello
w SayHello

"w" The symbol is a weak symbol that has not been specifically tagged as a weak object symbol.

And I test the old xcode 3.2, it works as expected.

Could anyone help me on this? Was it a bug of ld?

And I found more interested things. When I create a dummy lib to export the SayHello symbol in dynamic lib, it works as expected.

dummy.c:

int SayHello() {
    return;
}

$ gcc -dynamiclib -o libdummy.dylib dummy.c 
$ gcc weak.c libdummy.dylib 
$ ./a.out 
SayHello is present!

If the "libdummy.dylib" does not exist:

$ rm libdummy.dylib 
$ ./a.out 
SayHello is not present!

Works as expected! Weak symbol now in nm message, as expected:

$ nm -m a.out | grep Hello

                 (undefined) weak external _SayHello (from libdummy)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

还在原地等你 2024-11-14 16:30:00

今天在 GCC 12 和 Clang 14 上,如果没有 -undefineddynamic_lookup 选项,这仍然会出错:

Undefined symbols for architecture arm64:
  "_SayHello", referenced from:
      _main in weak-518bb6.o
ld: symbol(s) not found for architecture arm64

但它可以在选项集下正常工作:

% gcc-12 -undefined dynamic_lookup  -o weak weak.c && ./weak
ld: warning: -undefined dynamic_lookup may not work with chained fixups
SayHello is not present!
% cc -undefined dynamic_lookup  -o weak weak.c && ./weak
ld: warning: -undefined dynamic_lookup may not work with chained fixups
SayHello is not present!

gcc-12 (Homebrew GCC 12.2.0) 12.2.0
Apple clang version 14.0.0 (clang-1400.0.29.102)

C0deH4cker 调用了这个 评论中的链接。它详细介绍了该问题,包括一些解决方法。

This still errors today on GCC 12 and Clang 14 without the -undefined dynamic_lookup option:

Undefined symbols for architecture arm64:
  "_SayHello", referenced from:
      _main in weak-518bb6.o
ld: symbol(s) not found for architecture arm64

But it works correctly with the option set:

% gcc-12 -undefined dynamic_lookup  -o weak weak.c && ./weak
ld: warning: -undefined dynamic_lookup may not work with chained fixups
SayHello is not present!
% cc -undefined dynamic_lookup  -o weak weak.c && ./weak
ld: warning: -undefined dynamic_lookup may not work with chained fixups
SayHello is not present!

gcc-12 (Homebrew GCC 12.2.0) 12.2.0
Apple clang version 14.0.0 (clang-1400.0.29.102)

C0deH4cker called out this link in comments. It walks through the problem in detail including some workarounds.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文