1 #![cfg(all(feature = "read", feature = "write"))]
2 
3 use object::read::{Object, ObjectSection, ObjectSymbol};
4 use object::{read, write};
5 use object::{
6     Architecture, BinaryFormat, Endianness, SectionKind, SymbolFlags, SymbolKind, SymbolScope,
7 };
8 
9 #[test]
coff_x86_64_common()10 fn coff_x86_64_common() {
11     let mut object =
12         write::Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little);
13 
14     let symbol = write::Symbol {
15         name: b"v1".to_vec(),
16         value: 0,
17         size: 0,
18         kind: SymbolKind::Data,
19         scope: SymbolScope::Linkage,
20         weak: false,
21         section: write::SymbolSection::Undefined,
22         flags: SymbolFlags::None,
23     };
24     object.add_common_symbol(symbol, 4, 4);
25 
26     let symbol = write::Symbol {
27         name: b"v2".to_vec(),
28         value: 0,
29         size: 0,
30         kind: SymbolKind::Data,
31         scope: SymbolScope::Linkage,
32         weak: false,
33         section: write::SymbolSection::Undefined,
34         flags: SymbolFlags::None,
35     };
36     object.add_common_symbol(symbol, 8, 8);
37 
38     // Also check undefined symbols, which are very similar.
39     let symbol = write::Symbol {
40         name: b"v3".to_vec(),
41         value: 0,
42         size: 0,
43         kind: SymbolKind::Data,
44         scope: SymbolScope::Linkage,
45         weak: false,
46         section: write::SymbolSection::Undefined,
47         flags: SymbolFlags::None,
48     };
49     object.add_symbol(symbol);
50 
51     let bytes = object.write().unwrap();
52 
53     //std::fs::write(&"common.o", &bytes).unwrap();
54 
55     let object = read::File::parse(&bytes).unwrap();
56     assert_eq!(object.format(), BinaryFormat::Coff);
57     assert_eq!(object.architecture(), Architecture::X86_64);
58 
59     let mut symbols = object.symbols();
60 
61     let symbol = symbols.next().unwrap();
62     println!("{:?}", symbol);
63     assert_eq!(symbol.name(), Ok("v1"));
64     assert_eq!(symbol.kind(), SymbolKind::Data);
65     assert_eq!(symbol.section(), read::SymbolSection::Common);
66     assert_eq!(symbol.scope(), SymbolScope::Linkage);
67     assert_eq!(symbol.is_weak(), false);
68     assert_eq!(symbol.is_undefined(), false);
69     assert_eq!(symbol.address(), 0);
70     assert_eq!(symbol.size(), 4);
71 
72     let symbol = symbols.next().unwrap();
73     println!("{:?}", symbol);
74     assert_eq!(symbol.name(), Ok("v2"));
75     assert_eq!(symbol.kind(), SymbolKind::Data);
76     assert_eq!(symbol.section(), read::SymbolSection::Common);
77     assert_eq!(symbol.scope(), SymbolScope::Linkage);
78     assert_eq!(symbol.is_weak(), false);
79     assert_eq!(symbol.is_undefined(), false);
80     assert_eq!(symbol.address(), 0);
81     assert_eq!(symbol.size(), 8);
82 
83     let symbol = symbols.next().unwrap();
84     println!("{:?}", symbol);
85     assert_eq!(symbol.name(), Ok("v3"));
86     assert_eq!(symbol.kind(), SymbolKind::Data);
87     assert_eq!(symbol.section(), read::SymbolSection::Undefined);
88     assert_eq!(symbol.scope(), SymbolScope::Linkage);
89     assert_eq!(symbol.is_weak(), false);
90     assert_eq!(symbol.is_undefined(), true);
91     assert_eq!(symbol.address(), 0);
92     assert_eq!(symbol.size(), 0);
93 
94     let symbol = symbols.next();
95     assert!(symbol.is_none(), format!("unexpected symbol {:?}", symbol));
96 }
97 
98 #[test]
elf_x86_64_common()99 fn elf_x86_64_common() {
100     let mut object =
101         write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
102 
103     let symbol = write::Symbol {
104         name: b"v1".to_vec(),
105         value: 0,
106         size: 0,
107         kind: SymbolKind::Data,
108         scope: SymbolScope::Linkage,
109         weak: false,
110         section: write::SymbolSection::Undefined,
111         flags: SymbolFlags::None,
112     };
113     object.add_common_symbol(symbol, 4, 4);
114 
115     let symbol = write::Symbol {
116         name: b"v2".to_vec(),
117         value: 0,
118         size: 0,
119         kind: SymbolKind::Data,
120         scope: SymbolScope::Linkage,
121         weak: false,
122         section: write::SymbolSection::Undefined,
123         flags: SymbolFlags::None,
124     };
125     object.add_common_symbol(symbol, 8, 8);
126 
127     let bytes = object.write().unwrap();
128 
129     //std::fs::write(&"common.o", &bytes).unwrap();
130 
131     let object = read::File::parse(&bytes).unwrap();
132     assert_eq!(object.format(), BinaryFormat::Elf);
133     assert_eq!(object.architecture(), Architecture::X86_64);
134 
135     let mut symbols = object.symbols();
136 
137     let symbol = symbols.next().unwrap();
138     println!("{:?}", symbol);
139     assert_eq!(symbol.name(), Ok(""));
140 
141     let symbol = symbols.next().unwrap();
142     println!("{:?}", symbol);
143     assert_eq!(symbol.name(), Ok("v1"));
144     assert_eq!(symbol.kind(), SymbolKind::Data);
145     assert_eq!(symbol.section(), read::SymbolSection::Common);
146     assert_eq!(symbol.scope(), SymbolScope::Linkage);
147     assert_eq!(symbol.is_weak(), false);
148     assert_eq!(symbol.is_undefined(), false);
149     assert_eq!(symbol.address(), 0);
150     assert_eq!(symbol.size(), 4);
151 
152     let symbol = symbols.next().unwrap();
153     println!("{:?}", symbol);
154     assert_eq!(symbol.name(), Ok("v2"));
155     assert_eq!(symbol.kind(), SymbolKind::Data);
156     assert_eq!(symbol.section(), read::SymbolSection::Common);
157     assert_eq!(symbol.scope(), SymbolScope::Linkage);
158     assert_eq!(symbol.is_weak(), false);
159     assert_eq!(symbol.is_undefined(), false);
160     assert_eq!(symbol.address(), 0);
161     assert_eq!(symbol.size(), 8);
162 
163     let symbol = symbols.next();
164     assert!(symbol.is_none(), format!("unexpected symbol {:?}", symbol));
165 }
166 
167 #[test]
macho_x86_64_common()168 fn macho_x86_64_common() {
169     let mut object = write::Object::new(
170         BinaryFormat::MachO,
171         Architecture::X86_64,
172         Endianness::Little,
173     );
174 
175     let symbol = write::Symbol {
176         name: b"v1".to_vec(),
177         value: 0,
178         size: 0,
179         kind: SymbolKind::Data,
180         scope: SymbolScope::Linkage,
181         weak: false,
182         section: write::SymbolSection::Undefined,
183         flags: SymbolFlags::None,
184     };
185     object.add_common_symbol(symbol, 4, 4);
186 
187     let symbol = write::Symbol {
188         name: b"v2".to_vec(),
189         value: 0,
190         size: 0,
191         kind: SymbolKind::Data,
192         scope: SymbolScope::Linkage,
193         weak: false,
194         section: write::SymbolSection::Undefined,
195         flags: SymbolFlags::None,
196     };
197     object.add_common_symbol(symbol, 8, 8);
198 
199     let bytes = object.write().unwrap();
200 
201     //std::fs::write(&"common.o", &bytes).unwrap();
202 
203     let object = read::File::parse(&bytes).unwrap();
204     assert_eq!(object.format(), BinaryFormat::MachO);
205     assert_eq!(object.architecture(), Architecture::X86_64);
206 
207     let mut sections = object.sections();
208 
209     let common = sections.next().unwrap();
210     println!("{:?}", common);
211     let common_index = common.index();
212     assert_eq!(common.name(), Ok("__common"));
213     assert_eq!(common.segment_name(), Ok(Some("__DATA")));
214     assert_eq!(common.kind(), SectionKind::Common);
215     assert_eq!(common.size(), 16);
216     assert_eq!(common.data(), Ok(&[][..]));
217 
218     let section = sections.next();
219     assert!(
220         section.is_none(),
221         format!("unexpected section {:?}", section)
222     );
223 
224     let mut symbols = object.symbols();
225 
226     let symbol = symbols.next().unwrap();
227     println!("{:?}", symbol);
228     assert_eq!(symbol.name(), Ok("_v1"));
229     assert_eq!(symbol.kind(), SymbolKind::Data);
230     assert_eq!(symbol.section_index(), Some(common_index));
231     assert_eq!(symbol.scope(), SymbolScope::Linkage);
232     assert_eq!(symbol.is_weak(), false);
233     assert_eq!(symbol.is_undefined(), false);
234     assert_eq!(symbol.address(), 0);
235 
236     let symbol = symbols.next().unwrap();
237     println!("{:?}", symbol);
238     assert_eq!(symbol.name(), Ok("_v2"));
239     assert_eq!(symbol.kind(), SymbolKind::Data);
240     assert_eq!(symbol.section_index(), Some(common_index));
241     assert_eq!(symbol.scope(), SymbolScope::Linkage);
242     assert_eq!(symbol.is_weak(), false);
243     assert_eq!(symbol.is_undefined(), false);
244     assert_eq!(symbol.address(), 8);
245 
246     let symbol = symbols.next();
247     assert!(symbol.is_none(), format!("unexpected symbol {:?}", symbol));
248 }
249