HOMECOURSESSTUDENTSDONATIONSVIDEOSEVENTSTUTORIALSLINKSNEWSCONTACT


TUTORIALS 》 Dynamic linking without STDLIB in Linux user-space C programming

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:

[email protected]:~# 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:

[email protected]:~# 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
[email protected]:~# ./dytest
hello world
[email protected]:~#
[email protected]:~# 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
[email protected]:~#

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:


☆ Tutorials :: Arduino UNO Projects ↗


☆ Tutorials :: Network Software Development ↗


☆ Tutorials :: Research and Projects ↗


☆ Tutorials :: Linux (user-space), Systems Architecture ↗


☆ Tutorials :: Linux Kernel Software Development ↗


☆ Tutorials :: Linux Kernel Internals (PDFs) - by Ramin Farajpour ↗


☆ Tutorials :: Software Development (Programming) Tools ↗


☆ Tutorials :: Embedded Projects ↗

Join The Linux Channel :: Facebook Group ↗

Visit The Linux Channel :: on Youtube ↗


💗 Help shape the future: Sponsor/Donate


Recommended Topics:
Featured Video:
Watch on Youtube - x20f Code with Kiran - Live Coding | Linux Kernel Programming | Kernel Libraries | Part 1 ↗

Multi-Client TCP Server with pthreads Mutex Synchronized - Code-walk of viewer code - Sekhar Pariga ↗
Monday' 28-Sep-2020
Here is a code-walk of a git-hub source submitted by a viewer Sekhar Pariga, which is a Multi-client TCP Server with pthreads Mutex synchronized. Basically it is a Directory Listing Server, that serves ls, cd, pwd of directory functions to connecting TCP clients which are remotely (locally) executed by the server. Server is implemented using multi-thread pthread library, to serve multiple clients simultaneously. Server keeps the each accepted client session details in the queue data structure. Client session queue contains each clients socket-fd and present working directory as a queue node.

Adding your own Kernel Modules into Linux Kernel Source | Linux Kernel Programming ↗
Monday' 28-Sep-2020
Whenever you do custom kernel modules, you can optionally make it a part of existing Linux Kernel source. This does not mean you are submitting your kernel module to the mainline kernel source (i.e kernel.org Linux Kernel Foundation). What I meant is, you can make your kernel module(s) part of Linux Kernel source so that when you compile your kernel you can automatically compile your kernel module(s) too. As well when you create/modify kernel .config configuration file (such as via make menuconfig, etc), you can enable or disable your kernel module(s) too.
To do the same you have to register (and include) your custom Kernel Module's Kconfig and Makefile to the existing Kconfig and Makefile of the Linux Kernel source Here is a detailed multi-episode video of mine which gives the overall idea and the big-picture.

Roadmap - How to become Linux Kernel Developer - Device Drivers Programmer and a Systems Software Expert ↗
Monday' 28-Sep-2020
Many viewers and even sometimes my students ask me how I can become a kernel programmer or just device driver developer and so on. So I shot this video (and an add-on video) where I summarized steps and a roadmap to become a full-fledged Linux Kernel Developer.

Weekly News Digest - Week 03 - July 2020 ↗
Monday' 28-Sep-2020
The Linux Channel :: Weekly News Digest - Week 03 - July 2020
> Linux founder tells Intel to stop inventing 'magic instructions' and 'start fixing real problems'
> QNAP launches its first 2.5GbE network switch - QSW-1105-5T
> Japan's ARM-based Fugaku is the world's fastest supercomputer
> FreeBSD Back To Seeing Progress On 802.11ac WiFi Support, Ath10k Driver
> Sparkfun Launches the ZED-F9R GPS Dead Reckoning Raspberry Pi pHAT for Mobile Robots
> ODROID-N2 Plus SBC Gets Amlogic S922X Rev. C Processor Clocked at up to 2.4 GHz
> Rock Pi E SBC Comes with WiFi, Bluetooth, Two Ethernet Ports, and Optional PoE

Nmap Network Scanning ↗
Monday' 28-Sep-2020

IP-in-IP Tunneling Demystified - VPN Tunnels ↗
Monday' 28-Sep-2020
There can be many ways one can architect VPN Networks. The end objective is to tunnel private IP (typically LAN subnets) within public IP Networks (such as Internet). You can establish such a tunnel in various creative ways, such as Transport Mode, Tunnel Mode, IP-in-IP tunneling, etc. Also you can choose any transport layer protocol of your choice such as send VPN traffic via TCP, or via UDP and so on.

Management ↗
Monday' 28-Sep-2020

PHP installation ↗
Monday' 28-Sep-2020

Slow RGB Fade via Arduino UNO ↗
Monday' 28-Sep-2020

Generic VLOGs ↗
Monday' 28-Sep-2020
My general and tech VLOGs


Trending Video:
Watch on Youtube - x20f Code with Kiran - Live Coding | Linux Kernel Programming | Kernel Libraries | Part 1 ↗

MySQL database server installation ↗
Monday' 28-Sep-2020



Recommended Video:
Watch on Youtube - x20f Code with Kiran - Live Coding | Linux Kernel Programming | Kernel Libraries | Part 1 ↗