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§
- Cache
Entry - A processed library entry extracted from the cache.
- Extension
Directory - Directory of extension sections for future cache format enhancements.
- Extension
Section - A single extension section descriptor.
- LdCache
- The main cache structure representing a parsed
ld.so.cachefile. - NewCache
- Modern glibc cache format with hardware capabilities and extensions.
- NewFile
Entry - A single library entry in the new cache format with hardware capabilities.
- OldCache
- Legacy cache format used by ld.so-1.7.0.
- OldFile
Entry - A single library entry in the old cache format.
Enums§
- Cache
Error - Errors that can occur during cache parsing and processing.
- Cache
Format - Represents the different cache format combinations that can be found.