1 #![cfg(all(feature = "read", feature = "write"))]
2
3 use object::read::{Object, ObjectSection};
4 use object::{read, write};
5 use object::{
6 Architecture, BinaryFormat, Endianness, RelocationEncoding, RelocationKind, SectionKind,
7 SymbolFlags, SymbolKind, SymbolScope, SymbolSection,
8 };
9
10 mod bss;
11 mod common;
12 mod elf;
13 mod tls;
14
15 #[test]
coff_x86_64()16 fn coff_x86_64() {
17 let mut object =
18 write::Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little);
19
20 object.add_file_symbol(b"file.c".to_vec());
21
22 let text = object.section_id(write::StandardSection::Text);
23 object.append_section_data(text, &[1; 30], 4);
24
25 let func1_offset = object.append_section_data(text, &[1; 30], 4);
26 assert_eq!(func1_offset, 32);
27 let func1_symbol = object.add_symbol(write::Symbol {
28 name: b"func1".to_vec(),
29 value: func1_offset,
30 size: 32,
31 kind: SymbolKind::Text,
32 scope: SymbolScope::Linkage,
33 weak: false,
34 section: write::SymbolSection::Section(text),
35 flags: SymbolFlags::None,
36 });
37 object
38 .add_relocation(
39 text,
40 write::Relocation {
41 offset: 8,
42 size: 64,
43 kind: RelocationKind::Absolute,
44 encoding: RelocationEncoding::Generic,
45 symbol: func1_symbol,
46 addend: 0,
47 },
48 )
49 .unwrap();
50
51 let bytes = object.write().unwrap();
52 let object = read::File::parse(&bytes).unwrap();
53 assert_eq!(object.format(), BinaryFormat::Coff);
54 assert_eq!(object.architecture(), Architecture::X86_64);
55 assert_eq!(object.endianness(), Endianness::Little);
56
57 let mut sections = object.sections();
58
59 let text = sections.next().unwrap();
60 println!("{:?}", text);
61 let text_index = text.index();
62 assert_eq!(text.name(), Ok(".text"));
63 assert_eq!(text.kind(), SectionKind::Text);
64 assert_eq!(text.address(), 0);
65 assert_eq!(text.size(), 62);
66 assert_eq!(&text.data().unwrap()[..30], &[1; 30]);
67 assert_eq!(&text.data().unwrap()[32..62], &[1; 30]);
68
69 let mut symbols = object.symbols();
70
71 let (_, symbol) = symbols.next().unwrap();
72 println!("{:?}", symbol);
73 assert_eq!(symbol.name(), Some("file.c"));
74 assert_eq!(symbol.address(), 0);
75 assert_eq!(symbol.kind(), SymbolKind::File);
76 assert_eq!(symbol.section(), SymbolSection::None);
77 assert_eq!(symbol.scope(), SymbolScope::Compilation);
78 assert_eq!(symbol.is_weak(), false);
79
80 let (func1_symbol, symbol) = symbols.next().unwrap();
81 println!("{:?}", symbol);
82 assert_eq!(symbol.name(), Some("func1"));
83 assert_eq!(symbol.address(), func1_offset);
84 assert_eq!(symbol.kind(), SymbolKind::Text);
85 assert_eq!(symbol.section_index(), Some(text_index));
86 assert_eq!(symbol.scope(), SymbolScope::Linkage);
87 assert_eq!(symbol.is_weak(), false);
88 assert_eq!(symbol.is_undefined(), false);
89
90 let mut relocations = text.relocations();
91
92 let (offset, relocation) = relocations.next().unwrap();
93 println!("{:?}", relocation);
94 assert_eq!(offset, 8);
95 assert_eq!(relocation.kind(), RelocationKind::Absolute);
96 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
97 assert_eq!(relocation.size(), 64);
98 assert_eq!(
99 relocation.target(),
100 read::RelocationTarget::Symbol(func1_symbol)
101 );
102 assert_eq!(relocation.addend(), 0);
103 }
104
105 #[test]
elf_x86_64()106 fn elf_x86_64() {
107 let mut object =
108 write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
109
110 object.add_file_symbol(b"file.c".to_vec());
111
112 let text = object.section_id(write::StandardSection::Text);
113 object.append_section_data(text, &[1; 30], 4);
114
115 let func1_offset = object.append_section_data(text, &[1; 30], 4);
116 assert_eq!(func1_offset, 32);
117 let func1_symbol = object.add_symbol(write::Symbol {
118 name: b"func1".to_vec(),
119 value: func1_offset,
120 size: 32,
121 kind: SymbolKind::Text,
122 scope: SymbolScope::Linkage,
123 weak: false,
124 section: write::SymbolSection::Section(text),
125 flags: SymbolFlags::None,
126 });
127 object
128 .add_relocation(
129 text,
130 write::Relocation {
131 offset: 8,
132 size: 64,
133 kind: RelocationKind::Absolute,
134 encoding: RelocationEncoding::Generic,
135 symbol: func1_symbol,
136 addend: 0,
137 },
138 )
139 .unwrap();
140
141 let bytes = object.write().unwrap();
142 let object = read::File::parse(&bytes).unwrap();
143 assert_eq!(object.format(), BinaryFormat::Elf);
144 assert_eq!(object.architecture(), Architecture::X86_64);
145 assert_eq!(object.endianness(), Endianness::Little);
146
147 let mut sections = object.sections();
148
149 let section = sections.next().unwrap();
150 println!("{:?}", section);
151 assert_eq!(section.name(), Ok(""));
152 assert_eq!(section.kind(), SectionKind::Metadata);
153 assert_eq!(section.address(), 0);
154 assert_eq!(section.size(), 0);
155
156 let text = sections.next().unwrap();
157 println!("{:?}", text);
158 let text_index = text.index();
159 assert_eq!(text.name(), Ok(".text"));
160 assert_eq!(text.kind(), SectionKind::Text);
161 assert_eq!(text.address(), 0);
162 assert_eq!(text.size(), 62);
163 assert_eq!(&text.data().unwrap()[..30], &[1; 30]);
164 assert_eq!(&text.data().unwrap()[32..62], &[1; 30]);
165
166 let mut symbols = object.symbols();
167
168 let (_, symbol) = symbols.next().unwrap();
169 println!("{:?}", symbol);
170 assert_eq!(symbol.name(), Some(""));
171 assert_eq!(symbol.address(), 0);
172 assert_eq!(symbol.kind(), SymbolKind::Null);
173 assert_eq!(symbol.section_index(), None);
174 assert_eq!(symbol.scope(), SymbolScope::Unknown);
175 assert_eq!(symbol.is_weak(), false);
176 assert_eq!(symbol.is_undefined(), true);
177
178 let (_, symbol) = symbols.next().unwrap();
179 println!("{:?}", symbol);
180 assert_eq!(symbol.name(), Some("file.c"));
181 assert_eq!(symbol.address(), 0);
182 assert_eq!(symbol.kind(), SymbolKind::File);
183 assert_eq!(symbol.section(), SymbolSection::None);
184 assert_eq!(symbol.scope(), SymbolScope::Compilation);
185 assert_eq!(symbol.is_weak(), false);
186
187 let (func1_symbol, symbol) = symbols.next().unwrap();
188 println!("{:?}", symbol);
189 assert_eq!(symbol.name(), Some("func1"));
190 assert_eq!(symbol.address(), func1_offset);
191 assert_eq!(symbol.kind(), SymbolKind::Text);
192 assert_eq!(symbol.section_index(), Some(text_index));
193 assert_eq!(symbol.scope(), SymbolScope::Linkage);
194 assert_eq!(symbol.is_weak(), false);
195 assert_eq!(symbol.is_undefined(), false);
196
197 let mut relocations = text.relocations();
198
199 let (offset, relocation) = relocations.next().unwrap();
200 println!("{:?}", relocation);
201 assert_eq!(offset, 8);
202 assert_eq!(relocation.kind(), RelocationKind::Absolute);
203 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
204 assert_eq!(relocation.size(), 64);
205 assert_eq!(
206 relocation.target(),
207 read::RelocationTarget::Symbol(func1_symbol)
208 );
209 assert_eq!(relocation.addend(), 0);
210 }
211
212 #[test]
macho_x86_64()213 fn macho_x86_64() {
214 let mut object = write::Object::new(
215 BinaryFormat::MachO,
216 Architecture::X86_64,
217 Endianness::Little,
218 );
219
220 object.add_file_symbol(b"file.c".to_vec());
221
222 let text = object.section_id(write::StandardSection::Text);
223 object.append_section_data(text, &[1; 30], 4);
224
225 let func1_offset = object.append_section_data(text, &[1; 30], 4);
226 assert_eq!(func1_offset, 32);
227 let func1_symbol = object.add_symbol(write::Symbol {
228 name: b"func1".to_vec(),
229 value: func1_offset,
230 size: 32,
231 kind: SymbolKind::Text,
232 scope: SymbolScope::Linkage,
233 weak: false,
234 section: write::SymbolSection::Section(text),
235 flags: SymbolFlags::None,
236 });
237 object
238 .add_relocation(
239 text,
240 write::Relocation {
241 offset: 8,
242 size: 64,
243 kind: RelocationKind::Absolute,
244 encoding: RelocationEncoding::Generic,
245 symbol: func1_symbol,
246 addend: 0,
247 },
248 )
249 .unwrap();
250 object
251 .add_relocation(
252 text,
253 write::Relocation {
254 offset: 16,
255 size: 32,
256 kind: RelocationKind::Relative,
257 encoding: RelocationEncoding::Generic,
258 symbol: func1_symbol,
259 addend: -4,
260 },
261 )
262 .unwrap();
263
264 let bytes = object.write().unwrap();
265 let object = read::File::parse(&bytes).unwrap();
266 assert_eq!(object.format(), BinaryFormat::MachO);
267 assert_eq!(object.architecture(), Architecture::X86_64);
268 assert_eq!(object.endianness(), Endianness::Little);
269
270 let mut sections = object.sections();
271
272 let text = sections.next().unwrap();
273 println!("{:?}", text);
274 let text_index = text.index();
275 assert_eq!(text.name(), Ok("__text"));
276 assert_eq!(text.segment_name(), Ok(Some("__TEXT")));
277 assert_eq!(text.kind(), SectionKind::Text);
278 assert_eq!(text.address(), 0);
279 assert_eq!(text.size(), 62);
280 assert_eq!(&text.data().unwrap()[..30], &[1; 30]);
281 assert_eq!(&text.data().unwrap()[32..62], &[1; 30]);
282
283 let mut symbols = object.symbols();
284
285 let (func1_symbol, symbol) = symbols.next().unwrap();
286 println!("{:?}", symbol);
287 assert_eq!(symbol.name(), Some("_func1"));
288 assert_eq!(symbol.address(), func1_offset);
289 assert_eq!(symbol.kind(), SymbolKind::Text);
290 assert_eq!(symbol.section_index(), Some(text_index));
291 assert_eq!(symbol.scope(), SymbolScope::Linkage);
292 assert_eq!(symbol.is_weak(), false);
293 assert_eq!(symbol.is_undefined(), false);
294
295 let mut relocations = text.relocations();
296
297 let (offset, relocation) = relocations.next().unwrap();
298 println!("{:?}", relocation);
299 assert_eq!(offset, 8);
300 assert_eq!(relocation.kind(), RelocationKind::Absolute);
301 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
302 assert_eq!(relocation.size(), 64);
303 assert_eq!(
304 relocation.target(),
305 read::RelocationTarget::Symbol(func1_symbol)
306 );
307 assert_eq!(relocation.addend(), 0);
308
309 let (offset, relocation) = relocations.next().unwrap();
310 println!("{:?}", relocation);
311 assert_eq!(offset, 16);
312 assert_eq!(relocation.kind(), RelocationKind::Relative);
313 assert_eq!(relocation.encoding(), RelocationEncoding::X86RipRelative);
314 assert_eq!(relocation.size(), 32);
315 assert_eq!(
316 relocation.target(),
317 read::RelocationTarget::Symbol(func1_symbol)
318 );
319 assert_eq!(relocation.addend(), -4);
320 }
321