gcc 修复将libc与openssl一起使用时出现的动态链接器错误

dbf7pr2w  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(311)

下面是一个简单的hello world sha1-hasher,它使用的是openssl库。

#include <openssl/sha.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    system("printf '%s' 'hello world' | sha1sum");

    unsigned char digest[SHA_DIGEST_LENGTH];
    char digest_pr[(SHA_DIGEST_LENGTH)*2+1];
    SHA_CTX ctx;
    if(!SHA1_Init(&ctx)) return 1;
#define STR_STRLEN(A) A, (sizeof(A)/sizeof(*(A))-1)
    if(!SHA1_Update(&ctx,STR_STRLEN("hello"))) return EXIT_FAILURE;
    if(!SHA1_Update(&ctx,STR_STRLEN(" world"))) return EXIT_FAILURE;
    if(!SHA1_Final(digest,&ctx)) return EXIT_FAILURE;
    #define DIGITS "0123456789abcdef"
    for(size_t i=0;i<sizeof(digest);i++){
        digest_pr[i*2+0]=DIGITS[digest[i]/16];
        digest_pr[i*2+1]=DIGITS[digest[i]%16];
    }
    digest_pr[(SHA_DIGEST_LENGTH)*2]='\0';
    puts(digest_pr);
}

在安装了libssl-dev的Mint/Ubuntu上,我可以用$CC sha.c(其中CC是gcc、tcc或clang中的一个)编译并链接它,然后成功地运行它,但这在musl上不起作用,所以我获取了openssl源代码(git clone https://github.com/openssl/openssl),用./config --prefix=/usr/local/musl配置它,构建并安装它,现在是musl-gcc sha.c -lcrypto works,但运行LD_LIBRARY_PATH=/usr/local/musl/lib a.out让我得到:

Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __fprintf_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: makecontext: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: setcontext: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __register_atfork: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __memcpy_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __strcat_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: secure_getenv: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __vfprintf_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __syslog_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __memset_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __fread_chk: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: getcontext: symbol not found
Error relocating /usr/local/musl/lib/libcrypto.so.1.1: __sprintf_chk: symbol not found

是什么导致了这种情况,我该如何解决?

envsm3lx

envsm3lx1#

看起来您的OpenSSL不是针对musl-libc构建的。
musl-libc有它自己的动态链接器(参见https://wiki.musl-libc.org/faq.html),我们可以为musl动态链接器创建一个软链接。(-syslibdir是动态库(例如ld-musl-x86_64.so.1)所在的目录,参见https://wiki.musl-libc.org/getting-started.html

sudo ln -sf <YOUR-MUSL-LIBC-syslibdir/ld-musl-x86_64.so.1> /usr/bin/musl-ldd

然后,您可以看到openssl是否是针对musl-libc构建的。

$ musl-ldd <YOUR-OPENSSL-SRC>/libcrypto.so.1.1
        musl-ldd (0x7fcd5a749000)
        libdl.so.2 => musl-ldd (0x7fcd5a749000)
        libpthread.so.0 => musl-ldd (0x7fcd5a749000)
        libc.so.6 => musl-ldd (0x7fcd5a749000)
Error relocating ./libcrypto.so.1.1: makecontext: symbol not found
Error relocating ./libcrypto.so.1.1: setcontext: symbol not found
Error relocating ./libcrypto.so.1.1: __register_atfork: symbol not found
Error relocating ./libcrypto.so.1.1: getcontext: symbol not found

glib动态链接器工作正常,

$ ldd <YOUR-OPENSSL-SRC>/libcrypto.so.1.1
        linux-vdso.so.1 (0x00007ffd395a6000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007ff6e6e64000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff6e6e41000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff6e6c4f000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ff6e71d7000)

为了使用musl-libc构建OpenSSL,我们还必须指定linux头文件的位置,以避免出现<linux/mman.h>之类的错误
我只尝试过使用Clang和Musl-libc构建OpenSSL,这里是我使用的clang Package 器https://gist.github.com/randoruf/d1aa4e8acb0a852addcd2b84fc003719
(取自kakinaguru_zo编写的https://qiita.com/kakinaguru_zo/items/399ab7ea716a56aef50c
但是,在 Package 中仍然存在一些问题
这个 Package 器会链接startfile(e.g. Scrt1.o),而不管是构建库还是可执行文件。显然,只有可执行文件才需要startfile。因此,如果使用这个 Package 器,可能会遇到以下奇怪的错误(找不到main符号):

$ musl-clang mylibrary.c -shared -fPIC -o libmylibrary.so
$ musl-ldd libmylibrary.so
        ld-musl-x86_64.so.1 (0x7f49faef7000)
        libc.so => ld-musl-x86_64.so.1 (0x7f49faef7000)
Error relocating libmylibrary.so: main: symbol not found

如果库有启动文件,它可能有main的条目。这就是为什么找不到main符号的原因。
解决方案是不包含共享库的startfile(新的clang Package 器应该可以解决这个问题)。
另一个问题是test_errstrtest_catest_ssl_new将不会通过,因为操作系统及其软件是针对glibc构建的。
详情请登录我的博客https://randoruf.github.io/2022/08/23/musl-libc-ubuntu.html#about-the-test-case-in-openssl
最后一个问题是这个 Package 器只支持c语言。

相关问题