]> git.proxmox.com Git - rustc.git/blame - vendor/object/tests/round_trip/mod.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / vendor / object / tests / round_trip / mod.rs
CommitLineData
a2a8927a
XL
1#![cfg(all(feature = "read", feature = "write"))]
2
3use object::read::{Object, ObjectSection, ObjectSymbol};
4use object::{read, write};
5use object::{
6 Architecture, BinaryFormat, Endianness, RelocationEncoding, RelocationKind, SectionKind,
7 SymbolFlags, SymbolKind, SymbolScope, SymbolSection,
8};
9
10mod bss;
5099ac24 11mod coff;
a2a8927a
XL
12mod comdat;
13mod common;
14mod elf;
15mod macho;
5099ac24 16mod section_flags;
a2a8927a
XL
17mod tls;
18
19#[test]
20fn coff_x86_64() {
21 let mut object =
22 write::Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little);
23
24 object.add_file_symbol(b"file.c".to_vec());
25
26 let text = object.section_id(write::StandardSection::Text);
27 object.append_section_data(text, &[1; 30], 4);
28
29 let func1_offset = object.append_section_data(text, &[1; 30], 4);
30 assert_eq!(func1_offset, 32);
31 let func1_symbol = object.add_symbol(write::Symbol {
32 name: b"func1".to_vec(),
33 value: func1_offset,
34 size: 32,
35 kind: SymbolKind::Text,
36 scope: SymbolScope::Linkage,
37 weak: false,
38 section: write::SymbolSection::Section(text),
39 flags: SymbolFlags::None,
40 });
41 object
42 .add_relocation(
43 text,
44 write::Relocation {
45 offset: 8,
46 size: 64,
47 kind: RelocationKind::Absolute,
48 encoding: RelocationEncoding::Generic,
49 symbol: func1_symbol,
50 addend: 0,
51 },
52 )
53 .unwrap();
54
55 let bytes = object.write().unwrap();
56 let object = read::File::parse(&*bytes).unwrap();
57 assert_eq!(object.format(), BinaryFormat::Coff);
58 assert_eq!(object.architecture(), Architecture::X86_64);
59 assert_eq!(object.endianness(), Endianness::Little);
60
61 let mut sections = object.sections();
62
63 let text = sections.next().unwrap();
64 println!("{:?}", text);
65 let text_index = text.index();
66 assert_eq!(text.name(), Ok(".text"));
67 assert_eq!(text.kind(), SectionKind::Text);
68 assert_eq!(text.address(), 0);
69 assert_eq!(text.size(), 62);
70 assert_eq!(&text.data().unwrap()[..30], &[1; 30]);
71 assert_eq!(&text.data().unwrap()[32..62], &[1; 30]);
72
73 let mut symbols = object.symbols();
74
75 let symbol = symbols.next().unwrap();
76 println!("{:?}", symbol);
77 assert_eq!(symbol.name(), Ok("file.c"));
78 assert_eq!(symbol.address(), 0);
79 assert_eq!(symbol.kind(), SymbolKind::File);
80 assert_eq!(symbol.section(), SymbolSection::None);
81 assert_eq!(symbol.scope(), SymbolScope::Compilation);
82 assert_eq!(symbol.is_weak(), false);
83
84 let symbol = symbols.next().unwrap();
85 println!("{:?}", symbol);
86 let func1_symbol = symbol.index();
87 assert_eq!(symbol.name(), Ok("func1"));
88 assert_eq!(symbol.address(), func1_offset);
89 assert_eq!(symbol.kind(), SymbolKind::Text);
90 assert_eq!(symbol.section_index(), Some(text_index));
91 assert_eq!(symbol.scope(), SymbolScope::Linkage);
92 assert_eq!(symbol.is_weak(), false);
93 assert_eq!(symbol.is_undefined(), false);
94
95 let mut relocations = text.relocations();
96
97 let (offset, relocation) = relocations.next().unwrap();
98 println!("{:?}", relocation);
99 assert_eq!(offset, 8);
100 assert_eq!(relocation.kind(), RelocationKind::Absolute);
101 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
102 assert_eq!(relocation.size(), 64);
103 assert_eq!(
104 relocation.target(),
105 read::RelocationTarget::Symbol(func1_symbol)
106 );
107 assert_eq!(relocation.addend(), 0);
108
109 let map = object.symbol_map();
110 let symbol = map.get(func1_offset + 1).unwrap();
111 assert_eq!(symbol.address(), func1_offset);
112 assert_eq!(symbol.name(), "func1");
113 assert_eq!(map.get(func1_offset - 1), None);
114}
115
116#[test]
117fn elf_x86_64() {
118 let mut object =
119 write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
120
121 object.add_file_symbol(b"file.c".to_vec());
122
123 let text = object.section_id(write::StandardSection::Text);
124 object.append_section_data(text, &[1; 30], 4);
125
126 let func1_offset = object.append_section_data(text, &[1; 30], 4);
127 assert_eq!(func1_offset, 32);
128 let func1_symbol = object.add_symbol(write::Symbol {
129 name: b"func1".to_vec(),
130 value: func1_offset,
131 size: 32,
132 kind: SymbolKind::Text,
133 scope: SymbolScope::Linkage,
134 weak: false,
135 section: write::SymbolSection::Section(text),
136 flags: SymbolFlags::None,
137 });
138 object
139 .add_relocation(
140 text,
141 write::Relocation {
142 offset: 8,
143 size: 64,
144 kind: RelocationKind::Absolute,
145 encoding: RelocationEncoding::Generic,
146 symbol: func1_symbol,
147 addend: 0,
148 },
149 )
150 .unwrap();
151
152 let bytes = object.write().unwrap();
153 let object = read::File::parse(&*bytes).unwrap();
154 assert_eq!(object.format(), BinaryFormat::Elf);
155 assert_eq!(object.architecture(), Architecture::X86_64);
156 assert_eq!(object.endianness(), Endianness::Little);
157
158 let mut sections = object.sections();
159
160 let section = sections.next().unwrap();
161 println!("{:?}", section);
162 assert_eq!(section.name(), Ok(""));
163 assert_eq!(section.kind(), SectionKind::Metadata);
164 assert_eq!(section.address(), 0);
165 assert_eq!(section.size(), 0);
166
167 let text = sections.next().unwrap();
168 println!("{:?}", text);
169 let text_index = text.index();
170 assert_eq!(text.name(), Ok(".text"));
171 assert_eq!(text.kind(), SectionKind::Text);
172 assert_eq!(text.address(), 0);
173 assert_eq!(text.size(), 62);
174 assert_eq!(&text.data().unwrap()[..30], &[1; 30]);
175 assert_eq!(&text.data().unwrap()[32..62], &[1; 30]);
176
177 let mut symbols = object.symbols();
178
179 let symbol = symbols.next().unwrap();
180 println!("{:?}", symbol);
181 assert_eq!(symbol.name(), Ok(""));
182 assert_eq!(symbol.address(), 0);
183 assert_eq!(symbol.kind(), SymbolKind::Null);
184 assert_eq!(symbol.section_index(), None);
185 assert_eq!(symbol.scope(), SymbolScope::Unknown);
186 assert_eq!(symbol.is_weak(), false);
187 assert_eq!(symbol.is_undefined(), true);
188
189 let symbol = symbols.next().unwrap();
190 println!("{:?}", symbol);
191 assert_eq!(symbol.name(), Ok("file.c"));
192 assert_eq!(symbol.address(), 0);
193 assert_eq!(symbol.kind(), SymbolKind::File);
194 assert_eq!(symbol.section(), SymbolSection::None);
195 assert_eq!(symbol.scope(), SymbolScope::Compilation);
196 assert_eq!(symbol.is_weak(), false);
197
198 let symbol = symbols.next().unwrap();
199 println!("{:?}", symbol);
200 let func1_symbol = symbol.index();
201 assert_eq!(symbol.name(), Ok("func1"));
202 assert_eq!(symbol.address(), func1_offset);
203 assert_eq!(symbol.kind(), SymbolKind::Text);
204 assert_eq!(symbol.section_index(), Some(text_index));
205 assert_eq!(symbol.scope(), SymbolScope::Linkage);
206 assert_eq!(symbol.is_weak(), false);
207 assert_eq!(symbol.is_undefined(), false);
208
209 let mut relocations = text.relocations();
210
211 let (offset, relocation) = relocations.next().unwrap();
212 println!("{:?}", relocation);
213 assert_eq!(offset, 8);
214 assert_eq!(relocation.kind(), RelocationKind::Absolute);
215 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
216 assert_eq!(relocation.size(), 64);
217 assert_eq!(
218 relocation.target(),
219 read::RelocationTarget::Symbol(func1_symbol)
220 );
221 assert_eq!(relocation.addend(), 0);
222
223 let map = object.symbol_map();
224 let symbol = map.get(func1_offset + 1).unwrap();
225 assert_eq!(symbol.address(), func1_offset);
226 assert_eq!(symbol.name(), "func1");
227 assert_eq!(map.get(func1_offset - 1), None);
228}
229
230#[test]
231fn elf_any() {
232 for (arch, endian) in [
233 (Architecture::Aarch64, Endianness::Little),
f25598a0 234 (Architecture::Aarch64_Ilp32, Endianness::Little),
a2a8927a
XL
235 (Architecture::Arm, Endianness::Little),
236 (Architecture::Avr, Endianness::Little),
237 (Architecture::Bpf, Endianness::Little),
238 (Architecture::I386, Endianness::Little),
239 (Architecture::X86_64, Endianness::Little),
240 (Architecture::X86_64_X32, Endianness::Little),
241 (Architecture::Hexagon, Endianness::Little),
04454e1e 242 (Architecture::LoongArch64, Endianness::Little),
a2a8927a
XL
243 (Architecture::Mips, Endianness::Little),
244 (Architecture::Mips64, Endianness::Little),
245 (Architecture::Msp430, Endianness::Little),
246 (Architecture::PowerPc, Endianness::Big),
247 (Architecture::PowerPc64, Endianness::Big),
248 (Architecture::Riscv32, Endianness::Little),
249 (Architecture::Riscv64, Endianness::Little),
250 (Architecture::S390x, Endianness::Big),
f25598a0 251 (Architecture::Sbf, Endianness::Little),
a2a8927a 252 (Architecture::Sparc64, Endianness::Big),
f25598a0 253 (Architecture::Xtensa, Endianness::Little),
a2a8927a
XL
254 ]
255 .iter()
256 .copied()
257 {
258 let mut object = write::Object::new(BinaryFormat::Elf, arch, endian);
259
260 let section = object.section_id(write::StandardSection::Data);
261 object.append_section_data(section, &[1; 30], 4);
262 let symbol = object.section_symbol(section);
263
264 object
265 .add_relocation(
266 section,
267 write::Relocation {
268 offset: 8,
269 size: 32,
270 kind: RelocationKind::Absolute,
271 encoding: RelocationEncoding::Generic,
272 symbol,
273 addend: 0,
274 },
275 )
276 .unwrap();
277 if arch.address_size().unwrap().bytes() >= 8 {
278 object
279 .add_relocation(
280 section,
281 write::Relocation {
282 offset: 16,
283 size: 64,
284 kind: RelocationKind::Absolute,
285 encoding: RelocationEncoding::Generic,
286 symbol,
287 addend: 0,
288 },
289 )
290 .unwrap();
291 }
292
293 let bytes = object.write().unwrap();
294 let object = read::File::parse(&*bytes).unwrap();
295 println!("{:?}", object.architecture());
296 assert_eq!(object.format(), BinaryFormat::Elf);
297 assert_eq!(object.architecture(), arch);
298 assert_eq!(object.endianness(), endian);
299
300 let mut sections = object.sections();
301
302 let section = sections.next().unwrap();
303 println!("{:?}", section);
304 assert_eq!(section.name(), Ok(""));
305 assert_eq!(section.kind(), SectionKind::Metadata);
306 assert_eq!(section.address(), 0);
307 assert_eq!(section.size(), 0);
308
309 let data = sections.next().unwrap();
310 println!("{:?}", data);
311 assert_eq!(data.name(), Ok(".data"));
312 assert_eq!(data.kind(), SectionKind::Data);
313
314 let mut relocations = data.relocations();
315
316 let (offset, relocation) = relocations.next().unwrap();
317 println!("{:?}", relocation);
318 assert_eq!(offset, 8);
319 assert_eq!(relocation.kind(), RelocationKind::Absolute);
320 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
321 assert_eq!(relocation.size(), 32);
322 assert_eq!(relocation.addend(), 0);
323
324 if arch.address_size().unwrap().bytes() >= 8 {
325 let (offset, relocation) = relocations.next().unwrap();
326 println!("{:?}", relocation);
327 assert_eq!(offset, 16);
328 assert_eq!(relocation.kind(), RelocationKind::Absolute);
329 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
330 assert_eq!(relocation.size(), 64);
331 assert_eq!(relocation.addend(), 0);
332 }
333 }
334}
335
336#[test]
337fn macho_x86_64() {
338 let mut object = write::Object::new(
339 BinaryFormat::MachO,
340 Architecture::X86_64,
341 Endianness::Little,
342 );
343
344 object.add_file_symbol(b"file.c".to_vec());
345
346 let text = object.section_id(write::StandardSection::Text);
347 object.append_section_data(text, &[1; 30], 4);
348
349 let func1_offset = object.append_section_data(text, &[1; 30], 4);
350 assert_eq!(func1_offset, 32);
351 let func1_symbol = object.add_symbol(write::Symbol {
352 name: b"func1".to_vec(),
353 value: func1_offset,
354 size: 32,
355 kind: SymbolKind::Text,
356 scope: SymbolScope::Linkage,
357 weak: false,
358 section: write::SymbolSection::Section(text),
359 flags: SymbolFlags::None,
360 });
361 object
362 .add_relocation(
363 text,
364 write::Relocation {
365 offset: 8,
366 size: 64,
367 kind: RelocationKind::Absolute,
368 encoding: RelocationEncoding::Generic,
369 symbol: func1_symbol,
370 addend: 0,
371 },
372 )
373 .unwrap();
374 object
375 .add_relocation(
376 text,
377 write::Relocation {
378 offset: 16,
379 size: 32,
380 kind: RelocationKind::Relative,
381 encoding: RelocationEncoding::Generic,
382 symbol: func1_symbol,
383 addend: -4,
384 },
385 )
386 .unwrap();
387
388 let bytes = object.write().unwrap();
389 let object = read::File::parse(&*bytes).unwrap();
390 assert_eq!(object.format(), BinaryFormat::MachO);
391 assert_eq!(object.architecture(), Architecture::X86_64);
392 assert_eq!(object.endianness(), Endianness::Little);
393
394 let mut sections = object.sections();
395
396 let text = sections.next().unwrap();
397 println!("{:?}", text);
398 let text_index = text.index();
399 assert_eq!(text.name(), Ok("__text"));
400 assert_eq!(text.segment_name(), Ok(Some("__TEXT")));
401 assert_eq!(text.kind(), SectionKind::Text);
402 assert_eq!(text.address(), 0);
403 assert_eq!(text.size(), 62);
404 assert_eq!(&text.data().unwrap()[..30], &[1; 30]);
405 assert_eq!(&text.data().unwrap()[32..62], &[1; 30]);
406
407 let mut symbols = object.symbols();
408
409 let symbol = symbols.next().unwrap();
410 println!("{:?}", symbol);
411 let func1_symbol = symbol.index();
412 assert_eq!(symbol.name(), Ok("_func1"));
413 assert_eq!(symbol.address(), func1_offset);
414 assert_eq!(symbol.kind(), SymbolKind::Text);
415 assert_eq!(symbol.section_index(), Some(text_index));
416 assert_eq!(symbol.scope(), SymbolScope::Linkage);
417 assert_eq!(symbol.is_weak(), false);
418 assert_eq!(symbol.is_undefined(), false);
419
420 let mut relocations = text.relocations();
421
422 let (offset, relocation) = relocations.next().unwrap();
423 println!("{:?}", relocation);
424 assert_eq!(offset, 8);
425 assert_eq!(relocation.kind(), RelocationKind::Absolute);
426 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
427 assert_eq!(relocation.size(), 64);
428 assert_eq!(
429 relocation.target(),
430 read::RelocationTarget::Symbol(func1_symbol)
431 );
432 assert_eq!(relocation.addend(), 0);
433
434 let (offset, relocation) = relocations.next().unwrap();
435 println!("{:?}", relocation);
436 assert_eq!(offset, 16);
437 assert_eq!(relocation.kind(), RelocationKind::Relative);
438 assert_eq!(relocation.encoding(), RelocationEncoding::X86RipRelative);
439 assert_eq!(relocation.size(), 32);
440 assert_eq!(
441 relocation.target(),
442 read::RelocationTarget::Symbol(func1_symbol)
443 );
444 assert_eq!(relocation.addend(), -4);
445
446 let map = object.symbol_map();
447 let symbol = map.get(func1_offset + 1).unwrap();
448 assert_eq!(symbol.address(), func1_offset);
449 assert_eq!(symbol.name(), "_func1");
450 assert_eq!(map.get(func1_offset - 1), None);
451}