Crate ld_so_cache

Crate ld_so_cache 

Source
Expand description

§ld.so.cache Parser Library

This crate provides a comprehensive parser for ld.so.cache files used by the Linux dynamic linker. It supports both the legacy format (ld.so-1.7.0) and the modern glibc format with hardware capabilities.

§Quick Start

use ld_so_cache::parsers::parse_ld_cache;
use std::fs;

// Parse the system's ld.so.cache file
let data = fs::read("/etc/ld.so.cache")?;
let cache = parse_ld_cache(&data)?;

// Extract all library entries
let entries = cache.get_entries()?;
for entry in entries {
    println!("{} -> {}", entry.library_name, entry.library_path);
}

§Cache Formats

The library supports two cache formats:

  • Old Format: Used by ld.so-1.7.0, contains basic library mappings
  • New Format: Used by glibc, includes hardware capabilities and extensions

§Hardware Capabilities

The new format includes hardware capability flags that indicate processor features required by libraries. This allows the dynamic linker to select the most optimized version of a library for the current processor.

§Hardware Capability Bits

The 64-bit hwcap field encodes various processor features:

let entry = NewFileEntry {
    flags: 1,
    key: 0,
    value: 10,
    osversion_unused: 0,
    hwcap: 0x0002000000000000, // Example capability
};

// Extract ISA level (bits 52-61)
let isa_level = (entry.hwcap >> 52) & 0x3ff;
if isa_level >= 2 {
    println!("Requires x86-64-v2 or higher");
}

// Check for extension flag (bit 62)
let has_extensions = entry.hwcap & (1u64 << 62) != 0;
if has_extensions {
    println!("Library uses hardware capability extensions");
}

// Check for specific CPU features (bits 0-51)
// Note: Exact bit meanings are architecture-specific
let cpu_features = entry.hwcap & ((1u64 << 52) - 1);

§Error Handling

All parsing operations return Result<T, CacheError> for robust error handling. The library is designed to be resilient and will attempt to extract as much information as possible even from partially corrupted files.

§Common Error Patterns

use ld_so_cache::{parsers::parse_ld_cache, CacheError};
use std::fs;

// Read and parse cache file
let data = fs::read("/etc/ld.so.cache")?;
match parse_ld_cache(&data) {
    Ok(cache) => {
        // Successfully parsed cache
        match cache.get_entries() {
            Ok(entries) => println!("Found {} libraries", entries.len()),
            Err(CacheError::InvalidStringOffset(offset)) => {
                eprintln!("Corrupted string table at offset {}", offset);
            }
            Err(e) => eprintln!("Error extracting entries: {}", e),
        }
    }
    Err(CacheError::InvalidMagic) => {
        eprintln!("File is not a valid ld.so.cache");
    }
    Err(CacheError::TruncatedFile) => {
        eprintln!("Cache file appears to be truncated");
    }
    Err(e) => eprintln!("Parse error: {}", e),
}

§Graceful Degradation

When extracting entries, the library skips invalid entries rather than failing:

let cache = parse_ld_cache(&data)?;
let entries = cache.get_entries()?; // Will skip invalid entries
 
// Even if some entries are corrupted, we get the valid ones
for entry in entries {
    println!("{} -> {}", entry.library_name, entry.library_path);
}

Modules§

parsers
Binary parsers for ld.so.cache file formats.

Structs§

CacheEntry
A processed library entry extracted from the cache.
ExtensionDirectory
Directory of extension sections for future cache format enhancements.
ExtensionSection
A single extension section descriptor.
LdCache
The main cache structure representing a parsed ld.so.cache file.
NewCache
Modern glibc cache format with hardware capabilities and extensions.
NewFileEntry
A single library entry in the new cache format with hardware capabilities.
OldCache
Legacy cache format used by ld.so-1.7.0.
OldFileEntry
A single library entry in the old cache format.

Enums§

CacheError
Errors that can occur during cache parsing and processing.
CacheFormat
Represents the different cache format combinations that can be found.