1 use std
::collections
::HashMap
;
2 use std
::{env, fs, process}
;
5 write
, Object
, ObjectSection
, RelocationTarget
, SectionKind
, SymbolFlags
, SymbolKind
,
10 let mut args
= env
::args();
12 eprintln
!("Usage: {} <infile> <outfile>", args
.next().unwrap());
17 let in_file_path
= args
.next().unwrap();
18 let out_file_path
= args
.next().unwrap();
20 let in_file
= match fs
::File
::open(&in_file_path
) {
23 eprintln
!("Failed to open file '{}': {}", in_file_path
, err
,);
27 let in_file
= match unsafe { memmap::Mmap::map(&in_file) }
{
30 eprintln
!("Failed to map file '{}': {}", in_file_path
, err
,);
34 let in_object
= match object
::File
::parse(&*in_file
) {
37 eprintln
!("Failed to parse file '{}': {}", in_file_path
, err
);
42 let mut out_object
= write
::Object
::new(
44 in_object
.architecture(),
45 in_object
.endianness(),
47 out_object
.mangling
= write
::Mangling
::None
;
48 out_object
.flags
= in_object
.flags();
50 let mut out_sections
= HashMap
::new();
51 for in_section
in in_object
.sections() {
52 if in_section
.kind() == SectionKind
::Metadata
{
55 let section_id
= out_object
.add_section(
62 in_section
.name().unwrap().as_bytes().to_vec(),
65 let out_section
= out_object
.section_mut(section_id
);
66 if out_section
.is_bss() {
67 out_section
.append_bss(in_section
.size(), in_section
.align());
69 out_section
.set_data(in_section
.data().unwrap().into(), in_section
.align());
71 out_section
.flags
= in_section
.flags();
72 out_sections
.insert(in_section
.index(), section_id
);
75 let mut out_symbols
= HashMap
::new();
76 for (symbol_index
, in_symbol
) in in_object
.symbols() {
77 if in_symbol
.kind() == SymbolKind
::Null
{
80 let (section
, value
) = match in_symbol
.section() {
81 SymbolSection
::Unknown
=> panic
!("unknown symbol section for {:?}", in_symbol
),
82 SymbolSection
::None
=> (write
::SymbolSection
::None
, in_symbol
.address()),
83 SymbolSection
::Undefined
=> (write
::SymbolSection
::Undefined
, in_symbol
.address()),
84 SymbolSection
::Absolute
=> (write
::SymbolSection
::Absolute
, in_symbol
.address()),
85 SymbolSection
::Common
=> (write
::SymbolSection
::Common
, in_symbol
.address()),
86 SymbolSection
::Section(index
) => (
87 write
::SymbolSection
::Section(*out_sections
.get(&index
).unwrap()),
88 in_symbol
.address() - in_object
.section_by_index(index
).unwrap().address(),
91 let flags
= match in_symbol
.flags() {
92 SymbolFlags
::None
=> SymbolFlags
::None
,
93 SymbolFlags
::Elf { st_info, st_other }
=> SymbolFlags
::Elf { st_info, st_other }
,
94 SymbolFlags
::MachO { n_desc }
=> SymbolFlags
::MachO { n_desc }
,
95 SymbolFlags
::CoffSection
{
99 let associative_section
= *out_sections
.get(&associative_section
).unwrap();
100 SymbolFlags
::CoffSection
{
106 let out_symbol
= write
::Symbol
{
107 name
: in_symbol
.name().unwrap_or("").as_bytes().to_vec(),
109 size
: in_symbol
.size(),
110 kind
: in_symbol
.kind(),
111 scope
: in_symbol
.scope(),
112 weak
: in_symbol
.is_weak(),
116 let symbol_id
= out_object
.add_symbol(out_symbol
);
117 out_symbols
.insert(symbol_index
, symbol_id
);
120 for in_section
in in_object
.sections() {
121 if in_section
.kind() == SectionKind
::Metadata
{
124 let out_section
= *out_sections
.get(&in_section
.index()).unwrap();
125 for (offset
, in_relocation
) in in_section
.relocations() {
126 let symbol
= match in_relocation
.target() {
127 RelocationTarget
::Symbol(symbol
) => *out_symbols
.get(&symbol
).unwrap(),
128 RelocationTarget
::Section(section
) => {
129 out_object
.section_symbol(*out_sections
.get(§ion
).unwrap())
132 let out_relocation
= write
::Relocation
{
134 size
: in_relocation
.size(),
135 kind
: in_relocation
.kind(),
136 encoding
: in_relocation
.encoding(),
138 addend
: in_relocation
.addend(),
141 .add_relocation(out_section
, out_relocation
)
146 let out_data
= out_object
.write().unwrap();
147 if let Err(err
) = fs
::write(&out_file_path
, out_data
) {
148 eprintln
!("Failed to write file '{}': {}", out_file_path
, err
);