Skip to content

grigorypas/toy_dynamic_linker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Toy Dynamic Linker

An educational implementation of a dynamic linker for Linux x86_64, designed to demonstrate how dynamic linking works under the hood.

Overview

This project implements a minimal dynamic linker that can:

  • Load and parse ELF executables and shared libraries
  • Resolve symbols between libraries
  • Apply relocations (GOT, PLT, RELA)
  • Execute library initialization functions
  • Transfer control to the main program

The implementation is educational and focuses on clarity over performance or completeness.

Architecture

Core Components

  • src/toy_linker.c - Main dynamic linker entry point and orchestration
  • src/auxv.h - Auxiliary vector parsing (kernel-provided information)
  • src/program_header.h - ELF program header parsing
  • src/dynamic_section.h - Dynamic section parsing (DT_* entries)
  • src/loader.h - Library loading and memory mapping
  • src/symbol.h - Symbol table management and lookup
  • src/hash_table.h - Hash table for fast symbol resolution
  • src/relocation.h - Relocation processing (GOT/PLT patching)
  • src/init_libs.h - Library initialization function execution
  • src/util.h - System calls and utility functions (nostdlib environment)

Design Principles

  1. No Standard Library: Uses direct system calls to avoid circular dependencies with glibc
  2. Header-Only Implementation: All functions are static inline to avoid PLT issues - since the dynamic linker is responsible for resolving PLT entries, it cannot have its own unresolved PLT entries! The dynamic linker must be self-contained with no external function calls to resolve.
  3. Educational Focus: Extensive debug output and clear code structure to show each step
  4. Safety First: Validates pointers and handles errors gracefully - the dynamic linker runs before main program error handling is available

Building

# Create build directory
mkdir -p build
cd build

# Configure with CMake
cmake -G Ninja ..

# Build
ninja

Running the Example

The project includes a simple example program that demonstrates the dynamic linker functionality:

Example Components

  • example/simple_program.c - Main program with constructor function
  • example/simple_lib.c - Shared library with constructor and utility functions

Running the Example

# After building, run from the build directory
cd build/bin
./simple_program

Expected Output

=== Toy Dynamic Linker Debug Output ===
[Extensive debug information about loading, symbol resolution, relocations...]

=== Executing All Initialization Functions ===
Skipping init functions for dynamic linker itself
Executing init functions for main_executable
  Calling DT_INIT_ARRAY (1 functions)
    Function 0 at 401030
[PROGRAM INIT] simple_program constructor called!
Executing init functions for libsimple_lib.so
  Calling DT_INIT_ARRAY (1 functions)
    Function 0 at 7f7ef21f3030
[LIB INIT] simple_lib constructor called!
=== Initialization Complete ===

Hello from dynamically linked program!
This message is printed using the shared library function!

Educational Features

1. Constructor Functions

The example demonstrates __attribute__((constructor)) functions:

__attribute__((constructor))
void program_init(void) {
    // Called during program initialization
}

2. Library Functions

Shows how shared library functions are resolved and called:

// In simple_lib.c
int simple_strlen(const char *str);
void print_string(const char *message);

// Called from simple_program.c
int len = simple_strlen("Hello World");
print_string("Hello from library!");

3. Symbol Resolution

Demonstrates how symbols are resolved between the main program and shared libraries through GOT/PLT mechanisms.

4. Initialization Order

Shows the proper order of initialization:

  1. System libraries (skipped for safety)
  2. User shared libraries
  3. Main executable

Limitations

This is an educational toy implementation with several limitations:

What's NOT Implemented

  • TLS (Thread Local Storage) - No support for __thread variables
  • C++ Support - No C++ runtime initialization
  • System Library Init - Skips glibc initialization (requires full C runtime)
  • Advanced Relocations - Only basic RELA, GOT, and PLT relocations
  • Security Features - No RELRO, stack canaries, or other hardening
  • Performance Optimizations - Focus is on clarity, not speed

Why These Limitations Exist

  • TLS Complexity: Requires kernel support and complex setup
  • System Libraries: glibc initialization needs full C runtime environment
  • Educational Focus: Implementing everything would obscure the core concepts

How It Works

1. Startup Sequence

  1. Kernel loads the program and sets our toy linker as the interpreter
  2. Kernel provides auxiliary vector with program information
  3. Our _start() function receives control with the original stack

2. Dynamic Linking Process

  1. Parse auxiliary vector - Get program headers, entry point, etc.
  2. Parse program headers - Find PT_DYNAMIC segment
  3. Parse dynamic section - Extract needed libraries, symbol tables, etc.
  4. Load dependencies - Map shared libraries into memory
  5. Build symbol table - Create hash table for fast symbol lookup
  6. Apply relocations - Patch GOT/PLT entries with resolved addresses
  7. Execute initialization - Call constructor functions
  8. Transfer control - Jump to main program entry point

3. Memory Management

  • Uses custom malloc_custom() implementation based on mmap()
  • Cleans up all memory before transferring control
  • No memory leaks in the dynamic linker itself

Debugging

The toy linker provides extensive debug output showing:

  • Auxiliary vector contents
  • Program header information
  • Dynamic section entries
  • Library loading process
  • Symbol resolution details
  • Relocation application
  • Initialization function calls
  • Memory management operations

This makes it excellent for understanding how dynamic linking works step by step.

License

This project is for educational purposes. Feel free to use and modify for learning about dynamic linking.

About

Simple dynamic linker for educational purposes

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published