Articles of ld

运行g ++链接到特殊的库

这些想法可能看起来很奇怪 我在Gnu / Linux系统上创build了其他的环境,通过创build目录并将必要的文件复制到bin,lib,usr等等。 然后我做“chroot”,然后在里面做一些操作。 问题是环境中的所有文件都是从较旧的操作系统(2.4内核版本)中获取的。 但编译器必须采取现代(在现代语言标准的支持下)。 当我试图在环境中运行编译器时,出现错误: g++: /lib/libc.so.6: version `GLIBC_2.11' not found (required by g++) g++: /lib/libc.so.6: version `GLIBC_2.4' not found (required by g++) 然后,我将实际的libc.so.6复制到/ home / mylibs(内部环境)。 导出LD_LIBRARY_PATH: bash-3.00# export LD_LIBRARY_PATH="/home/mylibs/" 但似乎没有任何改变。 同样的错误依然存在。 下一个尝试是build立静态链接的gcc编译器。 不幸的是发生了一些问题( 静态链接的gcc )。 也许我从根本上是错误的…但是,我有没有其他的方式来build立可执行文件链接到旧的库,使用现代编译器? PS我的操作系统是ArchLinux。 'uname -r'显示'4.8.12-3-ARCH'。 最老的环境是由MCBC 3.0(俄文字母,不知道如何正确解密,也许武装部队的移动系统)与2.4内核版本。

C程序使用glibc编译而不是默认库:执行权限被拒绝

这是我在stackoverflow的第一个问题,所以我会尽力做好。 语境: 我想提供一个可以在每个Linux发行版上运行的程序(例如,将使用C ++ 11的程序,在没有C ++ 11程序库的系统上运行)。 为此,我想复制我的程序使用的所有库,并将它们放在一个带有可执行文件的文件夹中,以便它可以使用这些库而不是系统的库。 我有两个环境来testing: – Opensuse,(GNU libc)2.19 – Ubuntu,(Ubuntu EGLIBC 2.17-Oubuntu5.1)2.17 我在Opensuse下编译我的程序,并在Ubuntu下运行它。 该程序使用默认库时效果很好。 项目: 这里是main.c : int main(int ac, char **av) { printf("Hello World !\n"); } 这里是Opensuse下的文件夹树(在没有main.c和exec.sh的Ubuntu下也一样): + project | +— main.c +— a.out +— exec.sh +—+ lib | +— libc.so.6 +— ld-linux-x86-64.so.2 最后,当我用一个简单的编译启动程序时,这里是ldd和readelf: > gcc main.c -o a.out > […]

抑制共享库的编译时链接

我正在整合一个DRM库,因为安全原因,这个DRM库不能在代码库中保留。 DRM库在运行时只会在安全目标设备上处于清除状态,因此只能在运行时进行链接。 这给编译时链接带来了一个问题。 例如,如果我正在创build依赖DRM库libDrm.so的my_library.so,那么如果我简单地从构build中删除libDrm.so,则“ld:can not find -lDrm”gcc -fPIC -shared -o my_library.so my_library.c -L。 -lDrm 我知道dynamic加载libDrm.so的符号是一个解决scheme,但我不想编写代码在开发的这个阶段做dynamic加载。 我正在寻找快速和肮脏的东西。 我基本上想告诉LD忽略在编译时libDrm.so不能被find的事实,因为LD在运行时能够find它。 我怎样才能做到这一点? 我没有看到LD在编译时需要libDrm.so的原因,如果它在运行时可用,所以我希望LD足够灵活以允许这样做。 我目前正在考虑链接从stubs编译的libDrm.so版本,以使构build成功完成。 在运行时,从真正的实现中创build的libDrm.so版本将被链接到。 任何人都知道一个深奥的链接器选项,我可以使用LD来告诉LD延迟所有有关libDrm.so的链接操作,直到运行时?

在Linux中共享可执行的内存页面?

为了保存空间,是否可以在Linux上共享可执行页面? 我知道有共享的内存API可以用来在不同的进程之间共享内存,但我不认为这是用来做这件事的。 基本上,我想有一个共享内存区域,可以加载一些常用的共享库。 我想让dynamic连接器链接到预加载的(只读)图像,而不是必须将所有的共享库图像加载到每一个进程(这看起来像是浪费)。 这是可能的Linux内核? Darwin内核使用Mach VM的特性(称为commpages) (dyld共享高速caching存储在那里)来实现这一function。 交易是可以访问和分享每个进程之间的。 为了澄清,我知道共享对象(库)是什么。 目前,dynamic连接器在Linux上的作用是将所有必需的库加载到程序的地址空间中,这意味着每个与libc链接的应用程序在其地址空间中都会有一个libc映像。 在Darwin上,可以通过在一组共享内存页面上具有 libc的可执行文件(和其他只读文件)来消除这个问题。 共享图像的可写部分仍然是分开的。 编辑:我知道ELF格式不支持分离共享库的数据和文本段。 我没有使用ELF, 我使用了不同的二进制格式(使用我自己的binfmt内核模块和我自己的dynamic链接器) 。 如果Linux内核支持类似commpage的function,我很感兴趣。 编辑2:我能想到这样做的唯一方法是在内核中分配一大块内存,并将其映射到每个执行的二进制文件中。 第一次执行任何二进制文件时,dynamic连接器可以解除保护,填充所需的数据并保护它。 然后不知何故,内核将不得不确保内存段没有被其他任何东西修改,因为它会打开一个巨大的安全漏洞。 另一个

C / C ++未使用的内联函数未定义的引用

考虑下面的代码(这不是pthread特定的;其他的例子,例如涉及实时库的那些,performance出类似的行为): #define _GNU_SOURCE #include <pthread.h> inline void foo() { static cpu_set_t cpuset; pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); } int main(int argc, char *argv[]) { } 这是C和C ++中的有效程序。 所以我把这个内容保存到testc.c和testcpp.cpp并尝试构build。 当我用C++我没有遇到任何错误。 当我build立在C我得到一个未定义的引用错误。 现在,这个错误发生在-O1和-O3 。 是否有指示gcc做正确的事情(请参阅foo未使用,并跳过对pthread_setaffinity_np定义的要求)? 编辑:我认为这是显而易见的上下文,但错误信息是: /tmp/ccgARGVJ.o: In function `foo': testc.c:(.text+0x17): undefined reference to `pthread_setaffinity_np' 请注意,因为foo没有在主path中被引用,所以g++完全忽略了这个函数,但gcc却没有。 编辑2:让我再试一次。 函数foo ,以及对pthread_setaffinity_np的后续调用未使用。 主要function是空的。 只要看看它! 不知何故, g++发现foo不需要被包含,随后当我们故意省略-lpthread (并且用nm检查导出的符号确认foo和pthread_setaffinity_np都不需要引用)时,构build过程并没有发生。 gcc所得到的输出结果并不符合这个事实。 我在问这个问题,因为C ++和C前端在相同的input上似乎给出了不同的结果。 这似乎并不是一个初步问题,因为我希望这两个path都给出相同的链接错误,这就是为什么我强调这似乎是一个编译器问题。 如果C […]

为什么LD_PRELOAD似乎不能用wc写入

我正在玩LD_PRELOAD拦截libc调用,似乎写入调用不被拦截与wc,虽然它似乎与猫一起工作。 下面显示了一个精简版的问题。 RedHat Linux 2.6.9-42.ELsmp Makefile文件 writelib: gcc -Wall -rdynamic -fPIC -c write.c gcc -shared -Wl,-soname,libwrite.so -Wl,-export-dynamic -o libwrite.so write.o -ldl 为write.c: #include <stdio.h> #include <string.h> #ifndef __USE_GNU #define __USE_GNU #define __USE_GNU_DEFINED #endif #include <dlfcn.h> #ifdef __USE_GNU_DEFINED #undef __USE_GNU #undef __USE_GNU_DEFINED #endif #include <unistd.h> #include <stdlib.h> static ssize_t (*libc_write)(int fd, const void *buf, size_t len); […]

NVCC CUDA交叉编译无法find“-lcudart”

我已经在Ubuntu虚拟机上安装了CUDA 5.0和NVCC,甚至在编译CUDA C程序时也遇到了问题。 错误如下: user@ubuntu:~/CUDA$ nvcc helloworld.cu -o helloworld.o -target-cpu-arch=ARM -ccbin=/usr/bin/arm-linux-gnueabi-gcc-4.6 –machine=32 /usr/lib/gcc/arm-linux-gnueabi/4.6/../../../../arm-linux-gnueabi/bin/ld: skipping incompatible /usr/local/cuda-5.0/bin/../lib/libcudart.so when searching for -lcudart /usr/lib/gcc/arm-linux-gnueabi/4.6/../../../../arm-linux-gnueabi/bin/ld: skipping incompatible /usr/lib/libcudart.so when searching for -lcudart /usr/lib/gcc/arm-linux-gnueabi/4.6/../../../../arm-linux-gnueabi/bin/ld: cannot find -lcudart collect2: ld returned 1 exit status 我试图研究这个问题,并遇到这个链接: 跳过不兼容的libcudart.so当search-lcudart 所以我遵循了在该链接上提供的build议,并添加了 /usr/local/cuda-5.0/lib64 和 /usr/local/cuda-5.0/lib 到我的LD_LIBRARY_PATH环境variables,现在这是结果 user@ubuntu:~/CUDA$ echo $LD_LIBRARY_PATH /usr/local/cuda-5.0/lib:/usr/local/cuda-5.0/lib64 user@ubuntu:~/CUDA$ 但问题依然存在,请大家帮忙。

_dl_runtime_resolve – 何时将共享对象加载到内存中?

我们有一个高性能需求的消息处理系统。 最近我们已经注意到,第一条消息比后面的消息要长很多倍。 一系列转换和消息增强是在我们的系统中进行的,其中大部分是通过外部库来完成的。 我刚刚分析了这个问题(使用callgrind),比较一个消息的“运行”和许多消息的“运行”(提供比较基准)。 我看到的主要区别是占用了大量时间的函数“do_lookup_x”。 看看这个函数的各种调用,它们似乎都被通用函数调用:_dl_runtime_resolve。 不知道这个函数做了什么,但对我来说,这看起来像第一次使用各种共享库,然后由ld加载到内存中。 这是一个正确的假设吗? 二进制文件不会将共享库加载到内存中,直到它们被准备好使用,因此我们将看到第一条消息的大量减速,但是在后面的任何一条消息中都没有? 我们如何去避免这个? 注意:我们在微秒级别上运行。

链接无法find符号,但库被读取并且符号存在

我一直在试图编译我的项目,我得到undefined reference错误。 例如。: installertest.cpp:(.text+0x9d1): undefined reference to `XmlRpcValue::makeArray()' … installertest.cpp:(.text+0xede): undefined reference to `dbcancel' installertest.cpp:(.text+0xefd): undefined reference to `dbfcmd' installertest.cpp:(.text+0xf0f): undefined reference to `dbsqlexec' installertest.cpp:(.text+0xf2d): undefined reference to `SHA1_Init' … 我的命令是: g++ -o installertest \ -lsybdb \ -lxmlrpc \ -lxmlrpc_cpp \ -lxmlrpc_xmlparse \ -lxmlrpc_xmltok \ -lxmlrpc_util \ -lxmlrpc++ \ -lxmlrpc_server_cgi \ -lssl \ -std=c++0x \ […]

gcc – / usr / bin / ld错误:无法在/ usr / local / lib中find<library>,但ldconfig列出它,path添加到ld.so.conf

我尝试编译一个C ++代码,使用我也手动编译并安装在/ usr / local / lib中的库 在链接步骤中,软件的编译失败: /usr/bin/ld: error: cannot find -lcppdb g ++似乎不会在/usr/local/lib默认search,对于clang++ g++ -print-search-dirs # does not show /usr/local/lib 然而事实是/usr/local/lib在我的/etc/ld.so.conf而且我以root身份运行了ldconfig ,并且实际运行了ldconfig -p | grep cppdb ldconfig -p | grep cppdb显示我 libcppdb_sqlite3.so.0 (libc6) => /usr/local/lib/libcppdb_sqlite3.so.0 libcppdb_sqlite3.so (libc6) => /usr/local/lib/libcppdb_sqlite3.so libcppdb.so.0 (libc6) => /usr/local/lib/libcppdb.so.0 libcppdb.so (libc6) => /usr/local/lib/libcppdb.so 添加-L/usr/local/lib选项当然解决了这个问题,但是目标是使用configuration文件