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