Dynamic library loading in linux

Dynamically loading Linux shared libraries?

I do not wish to install it with ldconfig , etc. The target process looks like this:

#include #include void func1() < printf("%d\n", 1); >void func2() < printf("%d\n", 2); >void func3() < printf("%d\n", 3); >int main() < void* lib_handle = dlopen("/home/mike/Desktop/TargetProcess/MyLib.so.1.0.1", RTLD_NOW|RTLD_GLOBAL); if(lib_handle == NULL) < printf("Failed loading lib\n"); >else < printf("Loaded lib successfully\n"); void (*some_func)() = dlsym(lib_handle, "someFunc"); printf("%p\n", some_func); dlclose(lib_handle); >func1(); func2(); func3(); return 0; > 

The target is compiled as so:

all: gcc TestProg.c -ldl -o TestProg 
  1. With the dynamic loading with dlopen as above, why does my_load not appear to be called?
  2. With the same method, why does dlsym always return nil even though dlopen returns non-null? Similarly, nm doesn’t list either my_load or someFunc as symbols of the .so.
  3. Is it possible to use LD_PRELOAD to load the library? I tried copying the .so into the same directory as the target then invoking LD_PRELOAD=»./MyLib.so.1.0.1″ ./TestProg but again my_load seems not to be being called.

1 Answer 1

Your object files was no linked into your library:

gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc 

Change it to include your object file MyLib.o:

gcc MyLib.o -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc 

UPDATE: just tryed your command locally (without any MyLib.c or MyLib.o):

$ gcc -shared -W1,-soname,MyLib.so.1 -o MyLib.so.1.0.1 -lc && echo ok ok $ nm MyLib.so.1.0.1 xxxxxxxx a _DYNAMIC xxxxxxxx a _GLOBAL_OFFSET_TABLE_ w _Jv_RegisterClasses xxxxxxxx A __bss_start w __cxa_finalize@@xxxxxxxxxxx xxxxxxxx d __dso_handle w __gmon_start__ xxxxxxxx t __i686.get_pc_thunk.bx xxxxxxxx A _edata xxxxxxxx A _end xxxxxxxx T _fini xxxxxxxx T _init 

It is an empty dynamic library.

Источник

dynamically loading static library?

A static library is more or less just a collection of object files. If you want to use a static library in a program, you have to link the executable with it. The executable will then contain the static library (or the parts that you used).

Читайте также:  Удалить временные файлы линукс

If you want to load a static library at runtime using dlopen , you will have to first create a dynamic library libfoo.so containing it.

That workaround implies that I would have to create a shared library from a static library if I want to dynamically load it. This means that loading a static library dynamically is not possible and that only shared libraries can be used for dynamical loading? If so, than the quote I’ve stated from the source is not correct.

Opening a .a file using dlopen does not work (tested on Ubuntu 10.04). With the following example program:

dlopen error=/usr/lib/libz.a: invalid ELF header lib_handle=(nil) 

while when using /usr/lib/libz.so instead, I get:

dlopen error=(null) lib_handle=0x19d6030 

so the same code works for a shared object.

A .a is an archive containing one or more .o elf objects. Readelf and objdump won’t parse them. You must use ar to xtract the .o files from the archive. It is important to realize that if you are willing to spend the time writing and debugging a variant of load_elf() that can wrap one or more static libraries in a HAL you can load them dynamically and provide clients with a way to introspect their call entry points. This is nonstandard, and I can already feel the literati twitching like The Walking Jed. However, the ELF contains enough information to drop a library into a runtime environment and give properly coded client functions a way to discover the interface to the functions provided, and call them. This isn’t rocket science. It is simply tedious. An important concept here is that a developer who provides the .a archive and a include suite with the idea that they are restricting your use of the libraries, is just being annoying. It is not a serious impediment to using the library, or discovering how it does it’s job.

Читайте также:  Создать оболочку пользователю linux

Linked

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.14.43533

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Understanding Dynamic Library loading in Linux

I am trying to understand Dynamic Library loading in Linux from here [1] and want to clarify the concept. Concretely, when a dynamic library is loaded in a process in a Linux environment, it is loaded at any point in the address space. Now, a library has a code segment, and a data segment. The code segment’s address is not defined pre-linking so it is 0x0000000 while for data segment, some number is defined to be an address. But here is the trick, this address of data segment is not actually the true address. Actually, at whatever position code segment is loaded, data segment’s pre-defined address is added to it. Am I correct here? One more thing from the referenced article. What does this statement mean? However, we have the constraint that the shared library must still have a unqiue data instance in each process. While it would be possible to put the library data anywhere we want at runtime, this would require leaving behind relocations to patch the code and inform it where to actually find the data — destroying the always read-only property of the code and thus sharability. [1] http://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html

Читайте также:  How to run linux on android

1 Answer 1

Actually, at whatever position code segment is loaded, data segment’s pre-defined address is added to it.

Yes. The «VirtAddr» of the data segment will be added to base address.

What does this statement mean?

It means that when library accesses its own static data, we should not use relocations in the library code. Otherwise linker may need to patch the binary code, which leads to unsharing some parts of library codes between processes (if process1 loads library lib1 at 0x40000000, and process2 loads lib1 at 0x50000000, their data relocations will be different).

So, different solution is used in real life. Both library code and data are loaded together, and the offset between code and data is fixed for all cases. There is the «solution» after text you cited: http://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html

As you can see from the above headers, the solution is that the read-write data section is always put at a known offset from the code section of the library. This way, via the magic of virtual-memory, every process sees its own data section but can share the unmodified code. All that is needed to access data is some simple maths; address of thing I want = my current address + known fixed offset.

Источник

Оцените статью
Adblock
detector