TUTORIALS 》 Dynamic linking without STDLIB in Linux user-space C programming
This article is submitted by my student:
If you want to feature your article,
you can kindly contact me via email and send your article submissions (content and the resources).
Once they are reviewed, I should accept and post the same 🤗
🔗
Dynamic linker is the part of an operating system that loads and links the shared libraries needed by an executable.
Dynamic linking in Linux: Now, let us dig into the process of dynamically linked shared libraries in Linux.
When users start an application, they're invoking an Executable and Linking Format (ELF) image
(https://www.cs.stevens.edu/~jschauma/631/elf.html).
The kernel begins with the process of loading the ELF image into user space virtual memory. The kernel notices an ELF section called
.interp, which indicates the dynamic linker to be used /lib/ld-linux.so.
Example:
root@raminfp:~# readelf -l /bin/bash Elf file type is EXEC (Executable file) Entry point 0x420650 There are 9 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040 0x00000000000001f8 0x00000000000001f8 R E 8 INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238 0x000000000000001c 0x000000000000001c R 1 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x00000000000f27d4 0x00000000000f27d4 R E 200000 LOAD 0x00000000000f3628 0x00000000006f3628 0x00000000006f3628 0x000000000000b600 0x00000000000111d0 RW 200000 DYNAMIC 0x00000000000f5de0 0x00000000006f5de0 0x00000000006f5de0 0x00000000000001f0 0x00000000000001f0 RW 8 NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254 0x0000000000000044 0x0000000000000044 R 4 GNU_EH_FRAME 0x00000000000d72b0 0x00000000004d72b0 0x00000000004d72b0 0x0000000000004094 0x0000000000004094 R 4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 10 GNU_RELRO 0x00000000000f3628 0x00000000006f3628 0x00000000006f3628 0x00000000000029d8 0x00000000000029d8 R 1 Section to Segment mapping: Segment Sections... 00 01 .interp 02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 03 .init_array .fini_array .jcr .data.rel.ro .dynamic .got .got.plt .data .bss 04 .dynamic 05 .note.ABI-tag .note.gnu.build-id 06 .eh_frame_hdr 07 08 .init_array .fini_array .jcr .data.rel.ro .dynamic .got
We can find on the Internet many such examples of C source code about dynamic linker. But in this context we going to do Dynamic Linking of sample C user-space program without a standard lib (i.e STDLIB). In one of my earlier articles A Linux system call in C without a standard library I showed how to do a printf() in a sample C code with syscall without STDLIB. Now we can use/refer the same source code(mentioned in my previous article) for writing a dynamic linker.
And here is my GitHub project link
https://github.com/raminfp/linux_syscall/tree/master/C_syscall_without_standard_library_linux
in which you can refer assm_syscall.c:
int print(){ write(1, "hello world\n", 13); return 0; }
In the assm_syscall.c, we have this custom API intptr write(int fd, void const* data, uintptr nbytes).
So based on this we can create assm_syscall.h and to test dytest.c:
Here is the contents of dytest.c:
#include "assm_syscall.h" int main(void) { print(); return 0; }
And here is the contents of assm_syscall.h:
int print();
And here is the contents of the Makefile:
CC=gcc ASSMSYSCALLSOURCE=assm_syscall.c CONFIG=-nostdlib -fno-unwind-tables -fno-asynchronous-unwind-tables LIBDYNNAME=libdyn.so DYNTESTSOURCE=dytest.c DYNELF=dytest all: $(CC) -s -O2 $(CONFIG) -fPIC -shared -o $(LIBDYNNAME) $(ASSMSYSCALLSOURCE) $(CC) -o $(DYNELF) $(DYNTESTSOURCE) ./$(LIBDYNNAME) nodyn: $(CC) -s -O2 $(CONFIG) -fPIC -shared -o $(LIBDYNNAME) $(ASSMSYSCALLSOURCE) $(CC) -o $(DYNELF) $(DYNTESTSOURCE) clean: rm -rf $(LIBDYNNAME) $(DYNELF)
We can now compile the same as shown below:
root@raminfp:~# make gcc -s -O2 -nostdlib -fno-unwind-tables -fno-asynchronous-unwind-tables -fPIC -shared -o libdyn.so assm_syscall.c gcc -o dytest dytest.c ./libdyn.so root@raminfp:~# ./dytest hello world root@raminfp:~# root@raminfp:~# make clean
As you can see we got the output hello world successfully.
Now we can do a test compile once again with the option make nodyn, i.e without the dynamic linker libdyn.so. And
by doing so we get the following error.
gcc -s -O2 -nostdlib -fno-unwind-tables -fno-asynchronous-unwind-tables -fPIC -shared -o libdyn.so assm_syscall.c gcc -o dytest dytest.c /tmp/cc4JX5qm.o: In function `main': dytest.c:(.text+0xa): undefined reference to `print' collect2: error: ld returned 1 exit status Makefile:13: recipe for target 'nodyn' failed make: *** [nodyn] Error 1 root@raminfp:~#
Here is my entire GitHub source-code which you can download HERE for reference.
So this is how you can do dynamic linking without STDLIB in Linux user-space C programming.
Featured Video:
Suggested Topics:
Join The Linux Channel :: Facebook Group ↗
Visit The Linux Channel :: on Youtube ↗
💗 Help shape the future: Sponsor/Donate
Temas recomendados:
Featured Video:
Trending Video:
Recommended Video: