Articles of 共享库

如何知道共享库二进制文件是否使用-fPIC选项构build的

我正在开发embedded式Linux环境。 我有一组二进制格式的共享库(我没有源代码和Makefile),我想检查它们是否使用-fPIC选项编译。 有什么工具或方法来testing共享库二进制文件是否被编译过-fPIC? 问候。

共享库中库函数的select性静态链接

我想创build一个使用第三方静态库函数的共享库。 例如,来自libfoobar.a foo和bar 。 我知道我的主要应用程序也使用foo ,并将导出该符号。 所以我只是想在链接bar保存代码大小,并留下'富'未解决(因为它将由主应用程序提供)。 如果我包含libfoobar.a ,链接器ld将在我的共享库中包含这两个函数。 如果我不包含libfoobar.a ,我的库将无法访问functionbar因为应用程序本身并没有在bar链接。 问题: 有没有办法告诉ld在构build共享库时只parsing某些符号? 把libfoobar.a变成共享库? 从libfoobar.a提取包含functionbar文件并在链接器行上指定该文件? 不要担心,运行时加载器将使用您的应用程序中的bar ,这样共享库中的bar副本将不会被加载?

为什么共享库的ELF标头指定Linux作为OSABI?

我的Linux系统上的所有标准共享库(Fedora 9)都将ELFOSABI_NONE(0)指定为它们的OSABI。 这很好 – 但是我收到了ELF头文件中给出的OSABI为ELFOSABI_LINUX(3)的共享库。 这对于一个用于Linux系统的共享库来说听起来并不合理,但是对于我的其他所有库来说这是一个不同的值 – 所以当我试图用dlopen()打开这个库时,我的其他库的这个失败,错误“ELF文件操作系统ABI无效”。 我编译了FreeBSD实用程序brandelf.c,并使用它将OSABItypes更改为0,现在该库似乎可以与其他所有程序一起使用。 我只是想知道 – 你为什么认为这个库被标记为ELFOSABI_LINUX? 我猜也许他们在另一个系统上交叉编译,并指定一些gcc标志,导致这个值被设置到ELF头? 我试图实现类似的东西,但无法确定适当的gcc标志或标志。 我想知道可能的原因是什么,因为这个特定的供应商不会做任何事情,没有很多的手,我想能够说“你可能在做X,但这意味着我们必须修改你的库我们接受了他们之后“。

如何在共享库(.so)中使用共享库的同一进程的实例共享全局variables?

我有一个共享库(.so),在执行应用程序之前预先加载,并且在应用程序使用的共享库中有一些全局数据结构。 应用程序可以使用fork()创build其他进程,这些进程可以更新共享库中的全局数据结构。 我希望对所有stream程中的这些全球数据结构保持一致的看法。 有没有什么办法可以在Linux中完成? 我曾尝试使用shm_ *调用和mmap()将共享库的全局数据映射到共享段,但它不起作用。

Linux:如何将版本信息embedded共享库和二进制文件?

在Linux上,是否有将版本信息embedded到ELF二进制文件的方法? 我想在编译时embedded这个信息,以便稍后可以使用脚本来提取它。 一个骇客的方法是种植一些可以使用strings命令提取的东西。 有没有一个更传统的方法,类似于Visual Studio植物版本信息的Windows DLL(注意DLL属性中的版本选项卡)?

如何从Ocaml使用自己的共享库.so调用C ++代码?

我需要build立一个调用共享对象(Linux下的.so)的Ocaml / C ++模块, 只要编译一个简单的Ocaml / C ++存根就是一个问题,我pipe理这个东西,但是当我需要将.so和ocamlmklib或者ocamlopt连接起来的时候,它会失败 我在gcc 4.5下工作(c ++ 0x) 共享对象的文件: hello.hpp #include <iostream> #include <string> using namespace std; class HelloApplication { public : HelloApplication(); ~HelloApplication(); void say(string s); }; typedef HelloApplication *(*create_hello)(); hello.cpp: #include "hello.hpp" HelloApplication::HelloApplication(){} HelloApplication::~HelloApplication(){} void HelloApplication::say(string s) { cout << "Hello : " << s << endl; } extern […]

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 > […]

-finstrument-functions不适用于dynamic加载的g ++共享对象(.so)

我正在用Ubuntu上的g ++共享对象(.so)文件testing-finstrument函数。 我发现了一个奇怪的行为,即只有库是静态链接的,函数似乎才起作用。 如果我用dlopen / dlsym等链接到库,代码的function仍然有效,但它不会调用__cyg_profile *函数。 这里有一些代码来快速重现问题: MyLib.h #ifndef __MYLIB_H__ #define __MYLIB_H__ class MyLib { public: void sayHello(); }; #endif MyLib.cpp #include "MyLib.h" #include <iostream> using namespace std; void MyLib::sayHello() { cout<<"Hello"<<endl; } MyLibStub.cpp(到.so的C接口) #include "MyLib.h" extern "C" void LoadMyLib () { MyLib().sayHello(); } Trace.cpp #include <stdio.h> #ifdef __cplusplus extern "C" { void __cyg_profile_func_enter(void […]

在Linux上,为什么析构函数在C ++的全局variables的共享实例上运行两次?

在Linux上,我从一个定义了全局variables的静态库中生成了一些C ++代码。 这个全局variables的一个实例在引用它的符号的两个共享库之间共享。 当进程closures并且运行静态终止阶段时,我看到这个共享实例上的析构函数运行了两次! 据推测,每个图书馆每个卸载。 这个问题与我最近在这里看到的另一个问题密切相关: 相关的问题 。 这听起来像是一样的行为,但没有讨论为什么会发生。 有人知道背后的理论解释吗?

在共享库的构build选项中添加“-rpath,/ usr / lib”会导致段错误

我有一个你好世界计划。 #include <stdio.h> #include <stdlib.h> int main() { printf("hello world! \n"); return 0; } 我在链接阶段的程序-lmicroxml中添加-lmicroxml以链接到库libmicroxml.so 当我启动我的程序时,我得到了一个分段错误。 分段故障与libmicroxml.so的加载有关。 在我的helleo世界计划执行的strace之后: strace ./test execve("./test", ["./test"], [/* 11 vars */]) = 0 old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x4000000, -1, 0) = 0x777de000 stat("/etc/ld.so.cache", 0x7f944760) = -1 ENOENT (No such file or directory) open("/lib/libmicroxml.so.1", O_RDONLY) = -1 ENOENT (No such file or […]