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,
8 };
9
10 #[test]
coff_x86_64_tls()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
48 let (_, symbol) = symbols.next().unwrap();
49 println!("{:?}", symbol);
50 assert_eq!(symbol.name(), Some("tls1"));
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]
elf_x86_64_tls()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
121 let (_, symbol) = symbols.next().unwrap();
122 println!("{:?}", symbol);
123 assert_eq!(symbol.name(), Some(""));
124
125 let (_, symbol) = symbols.next().unwrap();
126 println!("{:?}", symbol);
127 assert_eq!(symbol.name(), Some("tls1"));
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
135 let (_, symbol) = symbols.next().unwrap();
136 println!("{:?}", symbol);
137 assert_eq!(symbol.name(), Some("tls2"));
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]
macho_x86_64_tls()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
219 let (_, symbol) = symbols.next().unwrap();
220 println!("{:?}", symbol);
221 assert_eq!(symbol.name(), Some("_tls1"));
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
228 let (tls1_init_symbol, symbol) = symbols.next().unwrap();
229 println!("{:?}", symbol);
230 assert_eq!(symbol.name(), Some("_tls1$tlv$init"));
231 assert_eq!(symbol.kind(), SymbolKind::Tls);
232 assert_eq!(symbol.section_index(), Some(thread_data_index));
233 assert_eq!(symbol.scope(), SymbolScope::Compilation);
234 assert_eq!(symbol.is_weak(), false);
235 assert_eq!(symbol.is_undefined(), false);
236
237 let (tlv_bootstrap_symbol, symbol) = symbols.next().unwrap();
238 println!("{:?}", symbol);
239 assert_eq!(symbol.name(), Some("__tlv_bootstrap"));
240 assert_eq!(symbol.kind(), SymbolKind::Unknown);
241 assert_eq!(symbol.section_index(), None);
242 assert_eq!(symbol.scope(), SymbolScope::Unknown);
243 assert_eq!(symbol.is_weak(), false);
244 assert_eq!(symbol.is_undefined(), true);
245
246 let (_, symbol) = symbols.next().unwrap();
247 println!("{:?}", symbol);
248 assert_eq!(symbol.name(), Some("_tls2"));
249 assert_eq!(symbol.kind(), SymbolKind::Tls);
250 assert_eq!(symbol.section_index(), Some(thread_vars_index));
251 assert_eq!(symbol.scope(), SymbolScope::Linkage);
252 assert_eq!(symbol.is_weak(), false);
253 assert_eq!(symbol.is_undefined(), false);
254
255 let (tls2_init_symbol, symbol) = symbols.next().unwrap();
256 println!("{:?}", symbol);
257 assert_eq!(symbol.name(), Some("_tls2$tlv$init"));
258 assert_eq!(symbol.kind(), SymbolKind::Tls);
259 assert_eq!(symbol.section_index(), Some(thread_bss_index));
260 assert_eq!(symbol.scope(), SymbolScope::Compilation);
261 assert_eq!(symbol.is_weak(), false);
262 assert_eq!(symbol.is_undefined(), false);
263
264 let mut relocations = thread_vars.relocations();
265
266 let (offset, relocation) = relocations.next().unwrap();
267 println!("{:?}", relocation);
268 assert_eq!(offset, 0);
269 assert_eq!(relocation.kind(), RelocationKind::Absolute);
270 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
271 assert_eq!(relocation.size(), 64);
272 assert_eq!(
273 relocation.target(),
274 read::RelocationTarget::Symbol(tlv_bootstrap_symbol)
275 );
276 assert_eq!(relocation.addend(), 0);
277
278 let (offset, relocation) = relocations.next().unwrap();
279 println!("{:?}", relocation);
280 assert_eq!(offset, 16);
281 assert_eq!(relocation.kind(), RelocationKind::Absolute);
282 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
283 assert_eq!(relocation.size(), 64);
284 assert_eq!(
285 relocation.target(),
286 read::RelocationTarget::Symbol(tls1_init_symbol)
287 );
288 assert_eq!(relocation.addend(), 0);
289
290 let (offset, relocation) = relocations.next().unwrap();
291 println!("{:?}", relocation);
292 assert_eq!(offset, 24);
293 assert_eq!(relocation.kind(), RelocationKind::Absolute);
294 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
295 assert_eq!(relocation.size(), 64);
296 assert_eq!(
297 relocation.target(),
298 read::RelocationTarget::Symbol(tlv_bootstrap_symbol)
299 );
300 assert_eq!(relocation.addend(), 0);
301
302 let (offset, relocation) = relocations.next().unwrap();
303 println!("{:?}", relocation);
304 assert_eq!(offset, 40);
305 assert_eq!(relocation.kind(), RelocationKind::Absolute);
306 assert_eq!(relocation.encoding(), RelocationEncoding::Generic);
307 assert_eq!(relocation.size(), 64);
308 assert_eq!(
309 relocation.target(),
310 read::RelocationTarget::Symbol(tls2_init_symbol)
311 );
312 assert_eq!(relocation.addend(), 0);
313 }
314