1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
use std::collections::HashMap;
use std::{env, fs, process};
use object::{write, Object, ObjectSection, RelocationTarget, SectionKind, SymbolKind};
fn main() {
let mut args = env::args();
if args.len() != 3 {
eprintln!("Usage: {} <infile> <outfile>", args.next().unwrap());
process::exit(1);
}
args.next();
let in_file_path = args.next().unwrap();
let out_file_path = args.next().unwrap();
let in_file = match fs::File::open(&in_file_path) {
Ok(file) => file,
Err(err) => {
eprintln!("Failed to open file '{}': {}", in_file_path, err,);
process::exit(1);
}
};
let in_file = match unsafe { memmap::Mmap::map(&in_file) } {
Ok(mmap) => mmap,
Err(err) => {
eprintln!("Failed to map file '{}': {}", in_file_path, err,);
process::exit(1);
}
};
let in_object = match object::File::parse(&*in_file) {
Ok(object) => object,
Err(err) => {
eprintln!("Failed to parse file '{}': {}", in_file_path, err);
process::exit(1);
}
};
let mut out_object = write::Object::new(in_object.format(), in_object.architecture());
out_object.mangling = write::Mangling::None;
let mut out_sections = HashMap::new();
for in_section in in_object.sections() {
if in_section.kind() == SectionKind::Metadata {
continue;
}
let section_id = out_object.add_section(
in_section.segment_name().unwrap_or("").as_bytes().to_vec(),
in_section.name().unwrap_or("").as_bytes().to_vec(),
in_section.kind(),
);
let out_section = out_object.section_mut(section_id);
if out_section.is_bss() {
out_section.append_bss(in_section.size(), in_section.align());
} else {
out_section.set_data(in_section.uncompressed_data().into(), in_section.align());
}
out_sections.insert(in_section.index(), section_id);
}
let mut out_symbols = HashMap::new();
for (symbol_index, in_symbol) in in_object.symbols() {
if in_symbol.kind() == SymbolKind::Null {
continue;
}
let (section, value) = match in_symbol.section_index() {
Some(index) => (
Some(*out_sections.get(&index).unwrap()),
in_symbol.address() - in_object.section_by_index(index).unwrap().address(),
),
None => (None, in_symbol.address()),
};
let out_symbol = write::Symbol {
name: in_symbol.name().unwrap_or("").as_bytes().to_vec(),
value,
size: in_symbol.size(),
kind: in_symbol.kind(),
scope: in_symbol.scope(),
weak: in_symbol.is_weak(),
section,
};
let symbol_id = out_object.add_symbol(out_symbol);
out_symbols.insert(symbol_index, symbol_id);
}
for in_section in in_object.sections() {
if in_section.kind() == SectionKind::Metadata {
continue;
}
let out_section = *out_sections.get(&in_section.index()).unwrap();
for (offset, in_relocation) in in_section.relocations() {
let symbol = match in_relocation.target() {
RelocationTarget::Symbol(symbol) => *out_symbols.get(&symbol).unwrap(),
RelocationTarget::Section(section) => {
out_object.section_symbol(*out_sections.get(§ion).unwrap())
}
};
let out_relocation = write::Relocation {
offset,
size: in_relocation.size(),
kind: in_relocation.kind(),
encoding: in_relocation.encoding(),
symbol,
addend: in_relocation.addend(),
};
out_object
.add_relocation(out_section, out_relocation)
.unwrap();
}
}
let out_data = out_object.write().unwrap();
if let Err(err) = fs::write(&out_file_path, out_data) {
eprintln!("Failed to write file '{}': {}", out_file_path, err);
process::exit(1);
}
}
|