Command documentation sourced from the linux-command project This comprehensive command reference is part of the linux-command documentation project.
ld - GNU Linker
The ld command is the GNU linker, a crucial component of the GNU Binutils package that combines object files and libraries to create executable programs or shared libraries. The linker resolves symbols, allocates memory, performs relocations, and generates the final output file in various formats like ELF, COFF, or a.out. ld is typically invoked automatically by compilers like GCC, but can also be used directly for fine-grained control over the linking process.
Basic Syntax
ld [options] [-o outputfile] objfile...
Common Options
Output Control
-o FILE- Set output file name-e SYMBOL- Set entry point symbol-s- Strip all symbols-S- Strip debugger symbols-x- Discard local symbols-r- Generate relocatable output
Library and Search Path
-lNAME- Link with library libNAME.so or libNAME.a-L PATH- Add directory to library search path-static- Link static libraries only-shared- Create shared library-Bstatic- Use static libraries for subsequent -l options-Bdynamic- Use shared libraries for subsequent -l options
Script and Layout Control
-T SCRIPT- Use linker script-Tdata ADDR- Set data segment address-Ttext ADDR- Set text segment address-Tbss ADDR- Set BSS segment address-format FORMAT- Set output format
Symbol Handling
-u SYMBOL- Start with undefined reference-defsym SYMBOL=EXPRESSION- Define symbol-wrap SYMBOL- Use wrapper function for symbol-export-dynamic- Export symbols for dynamic loading
Debugging and Information
-t- Print input files as processed-v- Print version information-M- Print link map-Map FILE- Write link map to file--cref- Output cross reference table
Architecture and Target
-m EMULATION- Set emulation--oformat FORMAT- Set output format-A ARCH- Set architecture--32- Generate 32-bit output--64- Generate 64-bit output
Usage Examples
Basic Linking Operations
Simple Executable Creation
# Link object files to create executable
ld -o myprogram main.o utils.o helper.o
# Link with standard library
ld -o myprogram main.o -lc -dynamic-linker /lib64/ld-linux-x86-64.so.2
# Link with specific library
ld -o myprogram main.o -lm -lpthread
# Link with custom library path
ld -o myprogram main.o -L./libs -lmylib
Creating Shared Libraries
# Create shared library
ld -shared -o libmylib.so module1.o module2.o
# Create shared library with soname
ld -shared -o libmylib.so.1.0 -soname libmylib.so.1 module.o
# Create shared library for position-independent code
ld -shared -fPIC -o libshared.so pic_object.o
# Create shared library with exported symbols
ld -shared -o libapi.so api.o --export-dynamic
Static Linking
# Link statically
ld -static -o static_program main.o -lc -lm
# Link with specific static library
ld -o program main.o -L./lib -l:libmylib.a
# Mix static and dynamic linking
ld -o program main.o -Bstatic -lstatic_lib -Bdynamic -ldynamic_lib
Advanced Linking
Linker Scripts
# Use custom linker script
ld -T custom_script.ld -o firmware.elf input.o
# Use default script with modifications
ld -T default.ld -Ttext 0x10000 -o kernel.o kernel_start.o
# Create linker script on the fly
ld -T <(echo "SECTIONS { .text 0x1000 : { *(.text) } }") -o program.o input.o
# Combine multiple scripts
ld -T base.ld -T extras.ld -o final.elf modules/*.o
Memory Layout Control
# Set specific text segment address
ld -Ttext 0x100000 -o bootloader.o boot.o
# Set data and BSS segments
ld -Ttext 0x1000 -Tdata 0x2000 -Tbss 0x3000 -o embedded.o
# Align sections
ld -Ttext 0x1000 -Tdata 0x2000 --section-start=.rodata=0x1800 -o aligned.o
# Create position-independent executable
ld -pie -o pie_executable.o main.o
Symbol Manipulation
# Define symbols at link time
ld -defsym VERSION=42 -o program.o main.o
# Force undefined symbol
ld -u missing_symbol -o program.o main.o -lm
# Wrap function calls
ld -wrap malloc -wrap free -o traced.o main.o tracer.o
# Export specific symbols only
ld -shared --version-script version.map -o libfiltered.so lib.o
# Create versioned symbols
ld -shared --version-script versions.lds -o libversioned.so modules.o
Cross-Platform Development
Different Output Formats
# Create ELF executable
ld --oformat elf64-x86-64 -o program.elf main.o
# Create COFF output
ld --oformat pe-i386 -o program.exe main.o
# Create flat binary
ld --oformat binary -o firmware.bin -Ttext 0x0 startup.o
# Create Mach-O for macOS
ld -o output.macho -arch x86_64 -macosx_version_min 10.15 input.o
Embedded Systems
# Link for ARM microcontroller
ld -m armelf -T arm_link.ld -o firmware.elf startup.o main.o
# Link with memory regions
ld -T memory.ld -o embedded.elf sections/*.o
# Create Intel HEX output
ld -o firmware.elf input.o
objcopy -O ihex firmware.elf firmware.hex
# Create Motorola S-record
ld -o firmware.elf input.o
objcopy -O srec firmware.elf firmware.srec
Practical Examples
System Programming
Kernel Development
# Link kernel with custom layout
ld -T kernel.ld -o vmlinuz head.o init.o kernel.o
# Create kernel with specific sections
ld -Ttext 0x100000 -Tdata 0x200000 -o kernel.o \
arch/x86/kernel/head.o \
init/main.o \
kernel/*.o
# Link kernel modules
ld -r -o module.ko module_core.o module_crypto.o
# Create bootable kernel image
ld -T boot.ld -o boot_image boot.o kernel.o
Library Development
# Create shared library with version info
ld -shared -o libcalc.so.1.2.3 \
-soname libcalc.so.1 \
calc.o math.o
# Create static library (using ar)
ar rcs libcalc.a calc.o math.o
# Create library with symbol versioning
ld -shared -o libcompat.so \
--version-script compat.map \
compat.o legacy.o
# Create library with exported symbols only
ld -shared -o libminimal.so \
--version-script minimal.vers \
modules/*.o
Application Development
Complex Application
# Link multi-module application
ld -o application \
main.o \
gui/gtk_interface.o \
network/protocol.o \
database/sqlite_wrapper.o \
-lgtk-3 -lsqlite3 -lpthread -lm
# Link with optimization
ld -o optimized_app main.o utils.o \
-Wl,--gc-sections \
-Wl,--strip-all
# Link with debugging information
ld -o debug_app main.o utils.o \
-g \
-Wl,--export-dynamic
Plugin System
# Create main executable for plugins
ld -o main_app main.o plugin_manager.o \
-ldl -rdynamic
# Create plugin as shared library
ld -shared -o plugin_text.so text_plugin.o
ld -shared -o plugin_image.so image_plugin.o
# Link with plugin API
ld -o main main.o -L./plugins -lplugin_api
Advanced Usage
Linker Script Development
Basic Linker Script
/* script.ld */
SECTIONS {
. = 0x10000; /* Start at 0x10000 */
.text : {
*(.text)
*(.rodata)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
*(COMMON)
}
}
Complex Memory Layout
/* memory.ld */
MEMORY {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
}
SECTIONS {
.text : {
*(.text*)
} > FLASH
.data : {
*(.data*)
_sdata = .;
} > RAM AT > FLASH
.bss : {
*(.bss*)
*(COMMON)
_sbss = .;
_ebss = .;
} > RAM
}
Symbol Versioning
Version Script
/* version.map */
LIBRARY_1.0 {
global:
func1;
func2;
local:
*;
};
LIBRARY_2.0 {
global:
func3;
func4;
} LIBRARY_1.0;
# Link with version script
ld -shared -o libexample.so.2.0 \
-soname libexample.so.2 \
--version-script version.map \
modules/*.o
Build System Integration
Makefile Integration
# Makefile snippet
CC = gcc
LD = ld
CFLAGS = -c -fPIC
all: program shared_lib
program: main.o utils.o
$(LD) -o $@ $^ -lc
shared_lib: module.o
$(LD) -shared -o libmodule.so $^
%.o: %.c
$(CC) $(CFLAGS) -o $@ $<
Complex Build Script
#!/bin/bash
# build.sh - Custom build script with ld
# Compile source files
gcc -c -Wall -Wextra -fPIC src/*.c
# Create static library
ar rcs libstatic.a *.o
# Create shared library
ld -shared -o libshared.so \
-soname libshared.so.1 \
*.o
# Create main executable
ld -o main_program main.o \
-L. -lshared -lpthread -lm
# Create debug version
ld -o debug_program main.o \
-g -L. -lstatic -rdynamic
Troubleshooting
Common Issues
Undefined References
# Problem: Undefined reference errors
ld -o program main.o
# error: undefined reference to 'printf'
# Solution: Link required libraries
ld -o program main.o -lc
# Solution: Link with math library
ld -o calculator calc.o -lm
# Solution: Add library search path
ld -o app main.o -L/usr/local/lib -lcustom
Symbol Resolution Issues
# Multiple definitions
ld -o program main.o lib1.o lib2.o
# error: multiple definition of 'global_var'
# Solution: Use weak symbols or
# wrap to resolve conflicts
ld -o program main.o -Wl,--allow-multiple-definition
# Solution: Use linker script to control symbol visibility
ld -T visibility.ld -o program *.o
Memory Layout Problems
# Text segment too large
ld -Ttext 0x1000 -o embedded.o modules/*.o
# error: region 'text' overflowed
# Solution: Increase address space or split sections
ld -Ttext 0x1000 -Tdata 0x100000 -o embedded.o modules/*.o
# Solution: Use garbage collection
ld --gc-sections -o embedded.o modules/*.o
Shared Library Issues
# Position-independent code errors
ld -shared -o lib.so module.o
# error: relocation R_X86_64_32 against `.rodata'
# Solution: Compile with -fPIC
gcc -fPIC -c module.c
ld -shared -o lib.so module.o
# Solution: Create position-independent executable
ld -pie -o pie_app main.o
Debugging Linker Issues
Getting Detailed Information
# Show link map
ld -Map linkmap.txt -o program *.o
# Verbose output
ld -v -o program *.o
# Show all input files
ld -t -o program *.o
# Cross reference table
ld --cref -o program *.o
# Print all symbols
nm -C program.o
Analyzing Libraries
# List library contents
nm libstatic.a
# List shared library symbols
nm -D libshared.so
# Show library dependencies
ldd executable
# Read ELF header
readelf -h program
# Show program headers
readelf -l program
Related Commands
gcc- GNU Compiler Collection (automatically invokes ld)g++- GNU C++ Compilerar- Create and manipulate static librariesnm- List symbols from object filesobjdump- Display information from object filesreadelf- Display ELF file informationldconfig- Configure dynamic linker run-time bindingsldd- Print shared library dependencies
Best Practices
- Let compilers invoke ld when possible for automatic library linking
- Use linker scripts for embedded systems and custom memory layouts
- Enable garbage collection (--gc-sections) to reduce binary size
- Use version scripts for shared library API management
- Set appropriate permissions on shared libraries (rwx for owner, rx for group/others)
- Maintain symbol compatibility when updating shared libraries
- Use position-independent code (-fPIC) for shared libraries
- Test linker configurations with different optimization levels
- Document custom linker scripts for maintainability
- Use build tools (make, cmake) to manage complex linking requirements
Performance Tips
- Use -Wl,--gc-sections to remove unused code
- Link static vs dynamic based on deployment requirements
- Optimize library search paths to reduce lookup time
- Use symbol versioning for backward compatibility
- Consider LTO (Link Time Optimization) with compiler support
- Prefer shared libraries for memory efficiency in large systems
- Use incremental linking for faster development cycles
- Organize object files by function for better cache utilization
The ld command is a powerful tool that provides complete control over the linking process, enabling developers to create optimized executables and libraries for various platforms and requirements. Understanding its capabilities is essential for system programming, embedded development, and performance-critical applications.