]> git.proxmox.com Git - rustc.git/blob - vendor/object-0.20.0/examples/objcopy.rs
New upstream version 1.49.0+dfsg1
[rustc.git] / vendor / object-0.20.0 / examples / objcopy.rs
1 use std::collections::HashMap;
2 use std::{env, fs, process};
3
4 use object::{
5 write, Object, ObjectSection, RelocationTarget, SectionKind, SymbolFlags, SymbolKind,
6 SymbolSection,
7 };
8
9 fn main() {
10 let mut args = env::args();
11 if args.len() != 3 {
12 eprintln!("Usage: {} <infile> <outfile>", args.next().unwrap());
13 process::exit(1);
14 }
15
16 args.next();
17 let in_file_path = args.next().unwrap();
18 let out_file_path = args.next().unwrap();
19
20 let in_file = match fs::File::open(&in_file_path) {
21 Ok(file) => file,
22 Err(err) => {
23 eprintln!("Failed to open file '{}': {}", in_file_path, err,);
24 process::exit(1);
25 }
26 };
27 let in_file = match unsafe { memmap::Mmap::map(&in_file) } {
28 Ok(mmap) => mmap,
29 Err(err) => {
30 eprintln!("Failed to map file '{}': {}", in_file_path, err,);
31 process::exit(1);
32 }
33 };
34 let in_object = match object::File::parse(&*in_file) {
35 Ok(object) => object,
36 Err(err) => {
37 eprintln!("Failed to parse file '{}': {}", in_file_path, err);
38 process::exit(1);
39 }
40 };
41
42 let mut out_object = write::Object::new(
43 in_object.format(),
44 in_object.architecture(),
45 in_object.endianness(),
46 );
47 out_object.mangling = write::Mangling::None;
48 out_object.flags = in_object.flags();
49
50 let mut out_sections = HashMap::new();
51 for in_section in in_object.sections() {
52 if in_section.kind() == SectionKind::Metadata {
53 continue;
54 }
55 let section_id = out_object.add_section(
56 in_section
57 .segment_name()
58 .unwrap()
59 .unwrap_or("")
60 .as_bytes()
61 .to_vec(),
62 in_section.name().unwrap().as_bytes().to_vec(),
63 in_section.kind(),
64 );
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());
68 } else {
69 out_section.set_data(in_section.data().unwrap().into(), in_section.align());
70 }
71 out_section.flags = in_section.flags();
72 out_sections.insert(in_section.index(), section_id);
73 }
74
75 let mut out_symbols = HashMap::new();
76 for (symbol_index, in_symbol) in in_object.symbols() {
77 if in_symbol.kind() == SymbolKind::Null {
78 continue;
79 }
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(),
89 ),
90 };
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 {
96 selection,
97 associative_section,
98 } => {
99 let associative_section = *out_sections.get(&associative_section).unwrap();
100 SymbolFlags::CoffSection {
101 selection,
102 associative_section,
103 }
104 }
105 };
106 let out_symbol = write::Symbol {
107 name: in_symbol.name().unwrap_or("").as_bytes().to_vec(),
108 value,
109 size: in_symbol.size(),
110 kind: in_symbol.kind(),
111 scope: in_symbol.scope(),
112 weak: in_symbol.is_weak(),
113 section,
114 flags,
115 };
116 let symbol_id = out_object.add_symbol(out_symbol);
117 out_symbols.insert(symbol_index, symbol_id);
118 }
119
120 for in_section in in_object.sections() {
121 if in_section.kind() == SectionKind::Metadata {
122 continue;
123 }
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(&section).unwrap())
130 }
131 };
132 let out_relocation = write::Relocation {
133 offset,
134 size: in_relocation.size(),
135 kind: in_relocation.kind(),
136 encoding: in_relocation.encoding(),
137 symbol,
138 addend: in_relocation.addend(),
139 };
140 out_object
141 .add_relocation(out_section, out_relocation)
142 .unwrap();
143 }
144 }
145
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);
149 process::exit(1);
150 }
151 }