# ld-so-cache
A comprehensive Rust parser for Linux `ld.so.cache` files with 100% compatibility with `ldconfig` output.
## Overview
The `ld.so.cache` file is used by the Linux dynamic linker to quickly locate shared libraries. This crate provides a complete parser that can read both legacy (ld.so-1.7.0) and modern (glibc) cache formats, extracting library names, paths, and hardware capability information.
## Features
- **Complete Format Support**: Handles both old (ld.so-1.7.0) and new (glibc) cache formats
- **Hardware Capabilities**: Parses hardware capability flags including ISA levels and processor features
- **Extension Support**: Handles cache extensions for future format enhancements
- **Error Resilience**: Gracefully handles corrupted or truncated cache files
- **100% ldconfig Compatibility**: Produces identical output to `ldconfig -p` across many major distributions
- **Cross-Platform**: Works on any platform that can read the cache files
## Verified Compatibility
This parser has been tested against real cache files from:
- **Debian**: Bookworm, Trixie
- **Ubuntu**: Jammy (22.04), Noble (24.04), Questing (25.04)
- **AlmaLinux**: 8, 9, 10
- **Red Hat**: UBI 8
All tests show **exact matches** with `ldconfig -p` output.
## Quick Start
### Library Usage
```rust
use ld_so_cache::parsers::parse_ld_cache;
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 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);
// Check if it's an ELF library
if entry.flags & 1 != 0 {
println!(" ELF library");
}
// Display hardware capabilities if present
if let Some(hwcap) = entry.hwcap {
let isa_level = (hwcap >> 52) & 0x3ff;
if isa_level > 0 {
println!(" Requires ISA level: {}", isa_level);
}
}
}
Ok(())
}
```
### Command Line Usage
The crate includes a CLI tool for inspecting cache files:
```bash
# Parse the system cache
ld-cache-parser
# Parse a specific cache file
ld-cache-parser -f /path/to/ld.so.cache
# Show detailed information including hardware capabilities
ld-cache-parser --verbose
# Output in JSON format
ld-cache-parser --format json
# Show only cache statistics
ld-cache-parser --stats
```
## Cache Formats
### Legacy Format (ld.so-1.7.0)
The old format provides basic library name to path mappings:
```rust
use ld_so_cache::OldFileEntry;
let entry = OldFileEntry {
flags: 1, // ELF library
key: 0, // Offset to library name
value: 10, // Offset to library path
};
```
### Modern Format (glibc)
The new format includes hardware capabilities and extensions:
```rust
use ld_so_cache::NewFileEntry;
let entry = NewFileEntry {
flags: 1,
key: 0,
value: 10,
osversion_unused: 0,
hwcap: 0x0020_0000_0000_1234, // Hardware capabilities
};
// Extract ISA level (bits 52-61)
let isa_level = (entry.hwcap >> 52) & 0x3ff;
// Check for extension flag (bit 62)
let has_extensions = entry.hwcap & (1u64 << 62) != 0;
// Get CPU features (bits 0-51)
let cpu_features = entry.hwcap & ((1u64 << 52) - 1);
```
## Hardware Capabilities
The parser correctly decodes hardware capability information:
- **ISA Levels**: x86-64-v2, x86-64-v3, etc. (bits 52-61)
- **Extension Flag**: Indicates additional capability data (bit 62)
- **CPU Features**: Various processor features like SSE, AVX (bits 0-51)
- **Architecture**: i386, x86-64, libx32 from flags field
## Error Handling
The library provides comprehensive error handling:
```rust
use ld_so_cache::{CacheError, parsers::parse_ld_cache};
match parse_ld_cache(&data) {
Ok(cache) => {
// Process cache entries
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!("Not a valid ld.so.cache file");
}
Err(CacheError::TruncatedFile) => {
eprintln!("Cache file is incomplete");
}
Err(e) => eprintln!("Parse error: {}", e),
}
```
## JSON Output
The library supports JSON serialization with proper formatting:
```json
{
"library_name": "libc.so.6",
"library_path": "/lib/x86_64-linux-gnu/libc.so.6",
"flags": 769,
"hwcap": "0x0000000000001000"
}
```
## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
ld-so-cache = "0.1"
```
Or install the CLI tool:
```bash
cargo install ld-so-cache
```
## Documentation
Full API documentation is available at [docs.rs](https://docs.rs/ld-so-cache).
The library includes extensive documentation with examples for all public APIs.
## Testing
The crate includes comprehensive tests:
- **Unit Tests**: All core parsing functionality
- **Integration Tests**: Real cache files from multiple distributions
- **Compatibility Tests**: Verification against `ldconfig -p` output
- **Documentation Tests**: All code examples are tested
Run tests with:
```bash
cargo test
```
## License
This project is licensed under the CC0 License - see the `LICENSE.md` file for details.
## AI Disclaimer
This library was built with the help of Claude Code. This README was significantly written by Claude. I wanted to get this quickly built, so I took a shortcut.