]>
Commit | Line | Data |
---|---|---|
fc512014 XL |
1 | #![cfg(all(feature = "read", feature = "write"))] |
2 | ||
3 | use object::pe; | |
4 | use object::read::{Object, ObjectComdat, ObjectSection, ObjectSymbol}; | |
5 | use object::{read, write}; | |
6 | use object::{ | |
7 | Architecture, BinaryFormat, ComdatKind, Endianness, SectionKind, SymbolFlags, SymbolKind, | |
8 | SymbolScope, | |
9 | }; | |
10 | ||
11 | #[test] | |
12 | fn coff_x86_64_comdat() { | |
13 | let mut object = | |
14 | write::Object::new(BinaryFormat::Coff, Architecture::X86_64, Endianness::Little); | |
15 | ||
16 | let (section1, offset) = | |
17 | object.add_subsection(write::StandardSection::Text, b"s1", &[0, 1, 2, 3], 4); | |
18 | object.section_symbol(section1); | |
19 | let (section2, _) = | |
20 | object.add_subsection(write::StandardSection::Data, b"s1", &[0, 1, 2, 3], 4); | |
21 | object.section_symbol(section2); | |
22 | ||
23 | let symbol = object.add_symbol(write::Symbol { | |
24 | name: b"s1".to_vec(), | |
25 | value: offset, | |
26 | size: 4, | |
27 | kind: SymbolKind::Data, | |
28 | scope: SymbolScope::Linkage, | |
29 | weak: false, | |
30 | section: write::SymbolSection::Section(section1), | |
31 | flags: SymbolFlags::None, | |
32 | }); | |
33 | ||
34 | object.add_comdat(write::Comdat { | |
35 | kind: ComdatKind::NoDuplicates, | |
36 | symbol, | |
37 | sections: vec![section1, section2], | |
38 | }); | |
39 | ||
40 | let bytes = object.write().unwrap(); | |
41 | ||
42 | //std::fs::write(&"comdat.o", &bytes).unwrap(); | |
43 | ||
44 | let object = read::File::parse(&bytes).unwrap(); | |
45 | assert_eq!(object.format(), BinaryFormat::Coff); | |
46 | assert_eq!(object.architecture(), Architecture::X86_64); | |
47 | ||
48 | let mut sections = object.sections(); | |
49 | ||
50 | let section1 = sections.next().unwrap(); | |
51 | println!("{:?}", section1); | |
52 | let section1_index = section1.index(); | |
53 | assert_eq!(section1.name(), Ok(".text$s1")); | |
54 | assert_eq!(section1.kind(), SectionKind::Text); | |
55 | assert_eq!(section1.address(), 0); | |
56 | assert_eq!(section1.size(), 4); | |
57 | ||
58 | let section2 = sections.next().unwrap(); | |
59 | println!("{:?}", section2); | |
60 | let section2_index = section2.index(); | |
61 | assert_eq!(section2.name(), Ok(".data$s1")); | |
62 | assert_eq!(section2.kind(), SectionKind::Data); | |
63 | assert_eq!(section2.address(), 0); | |
64 | assert_eq!(section2.size(), 4); | |
65 | ||
66 | let mut symbols = object.symbols(); | |
67 | ||
68 | let symbol = symbols.next().unwrap(); | |
69 | println!("{:?}", symbol); | |
70 | assert_eq!(symbol.name(), Ok(".text$s1")); | |
71 | assert_eq!(symbol.kind(), SymbolKind::Section); | |
72 | assert_eq!( | |
73 | symbol.section(), | |
74 | read::SymbolSection::Section(section1.index()) | |
75 | ); | |
76 | assert_eq!( | |
77 | symbol.flags(), | |
78 | SymbolFlags::CoffSection { | |
79 | selection: pe::IMAGE_COMDAT_SELECT_NODUPLICATES, | |
80 | associative_section: None | |
81 | } | |
82 | ); | |
83 | ||
84 | let symbol = symbols.next().unwrap(); | |
85 | println!("{:?}", symbol); | |
86 | assert_eq!(symbol.name(), Ok(".data$s1")); | |
87 | assert_eq!(symbol.kind(), SymbolKind::Section); | |
88 | assert_eq!( | |
89 | symbol.section(), | |
90 | read::SymbolSection::Section(section2.index()) | |
91 | ); | |
92 | assert_eq!( | |
93 | symbol.flags(), | |
94 | SymbolFlags::CoffSection { | |
95 | selection: pe::IMAGE_COMDAT_SELECT_ASSOCIATIVE, | |
96 | associative_section: Some(section1_index) | |
97 | } | |
98 | ); | |
99 | ||
100 | let symbol = symbols.next().unwrap(); | |
101 | let symbol_index = symbol.index(); | |
102 | println!("{:?}", symbol); | |
103 | assert_eq!(symbol.name(), Ok("s1")); | |
104 | assert_eq!(symbol.kind(), SymbolKind::Data); | |
105 | assert_eq!( | |
106 | symbol.section(), | |
107 | read::SymbolSection::Section(section1.index()) | |
108 | ); | |
109 | assert_eq!(symbol.scope(), SymbolScope::Linkage); | |
110 | assert_eq!(symbol.is_weak(), false); | |
111 | assert_eq!(symbol.is_undefined(), false); | |
112 | assert_eq!(symbol.address(), 0); | |
113 | ||
114 | let symbol = symbols.next(); | |
115 | assert!(symbol.is_none(), format!("unexpected symbol {:?}", symbol)); | |
116 | ||
117 | let mut comdats = object.comdats(); | |
118 | ||
119 | let comdat = comdats.next().unwrap(); | |
120 | println!("{:?}", comdat); | |
121 | assert_eq!(comdat.kind(), ComdatKind::NoDuplicates); | |
122 | assert_eq!(comdat.symbol(), symbol_index); | |
123 | ||
124 | let mut comdat_sections = comdat.sections(); | |
125 | assert_eq!(comdat_sections.next(), Some(section1_index)); | |
126 | assert_eq!(comdat_sections.next(), Some(section2_index)); | |
127 | assert_eq!(comdat_sections.next(), None); | |
128 | } | |
129 | ||
130 | #[test] | |
131 | fn elf_x86_64_common() { | |
132 | let mut object = | |
133 | write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little); | |
134 | ||
135 | let (section1, offset) = | |
136 | object.add_subsection(write::StandardSection::Text, b"s1", &[0, 1, 2, 3], 4); | |
137 | let (section2, _) = | |
138 | object.add_subsection(write::StandardSection::Data, b"s1", &[0, 1, 2, 3], 4); | |
139 | ||
140 | let symbol = object.add_symbol(write::Symbol { | |
141 | name: b"s1".to_vec(), | |
142 | value: offset, | |
143 | size: 4, | |
144 | kind: SymbolKind::Data, | |
145 | scope: SymbolScope::Linkage, | |
146 | weak: false, | |
147 | section: write::SymbolSection::Section(section1), | |
148 | flags: SymbolFlags::None, | |
149 | }); | |
150 | ||
151 | object.add_comdat(write::Comdat { | |
152 | kind: ComdatKind::Any, | |
153 | symbol, | |
154 | sections: vec![section1, section2], | |
155 | }); | |
156 | ||
157 | let bytes = object.write().unwrap(); | |
158 | ||
159 | //std::fs::write(&"comdat.o", &bytes).unwrap(); | |
160 | ||
161 | let object = read::File::parse(&bytes).unwrap(); | |
162 | assert_eq!(object.format(), BinaryFormat::Elf); | |
163 | assert_eq!(object.architecture(), Architecture::X86_64); | |
164 | ||
165 | let mut sections = object.sections(); | |
166 | ||
167 | let section = sections.next().unwrap(); | |
168 | println!("{:?}", section); | |
169 | assert_eq!(section.name(), Ok("")); | |
170 | ||
171 | let section = sections.next().unwrap(); | |
172 | println!("{:?}", section); | |
173 | assert_eq!(section.name(), Ok(".group")); | |
174 | ||
175 | let section1 = sections.next().unwrap(); | |
176 | println!("{:?}", section1); | |
177 | let section1_index = section1.index(); | |
178 | assert_eq!(section1.name(), Ok(".text.s1")); | |
179 | assert_eq!(section1.kind(), SectionKind::Text); | |
180 | assert_eq!(section1.address(), 0); | |
181 | assert_eq!(section1.size(), 4); | |
182 | ||
183 | let section2 = sections.next().unwrap(); | |
184 | println!("{:?}", section2); | |
185 | let section2_index = section2.index(); | |
186 | assert_eq!(section2.name(), Ok(".data.s1")); | |
187 | assert_eq!(section2.kind(), SectionKind::Data); | |
188 | assert_eq!(section2.address(), 0); | |
189 | assert_eq!(section2.size(), 4); | |
190 | ||
191 | let mut symbols = object.symbols(); | |
192 | ||
193 | let symbol = symbols.next().unwrap(); | |
194 | println!("{:?}", symbol); | |
195 | assert_eq!(symbol.name(), Ok("")); | |
196 | ||
197 | let symbol = symbols.next().unwrap(); | |
198 | let symbol_index = symbol.index(); | |
199 | println!("{:?}", symbol); | |
200 | assert_eq!(symbol.name(), Ok("s1")); | |
201 | assert_eq!(symbol.kind(), SymbolKind::Data); | |
202 | assert_eq!( | |
203 | symbol.section(), | |
204 | read::SymbolSection::Section(section1.index()) | |
205 | ); | |
206 | assert_eq!(symbol.scope(), SymbolScope::Linkage); | |
207 | assert_eq!(symbol.is_weak(), false); | |
208 | assert_eq!(symbol.is_undefined(), false); | |
209 | assert_eq!(symbol.address(), 0); | |
210 | ||
211 | let symbol = symbols.next(); | |
212 | assert!(symbol.is_none(), format!("unexpected symbol {:?}", symbol)); | |
213 | ||
214 | let mut comdats = object.comdats(); | |
215 | ||
216 | let comdat = comdats.next().unwrap(); | |
217 | println!("{:?}", comdat); | |
218 | assert_eq!(comdat.kind(), ComdatKind::Any); | |
219 | assert_eq!(comdat.symbol(), symbol_index); | |
220 | ||
221 | let mut comdat_sections = comdat.sections(); | |
222 | assert_eq!(comdat_sections.next(), Some(section1_index)); | |
223 | assert_eq!(comdat_sections.next(), Some(section2_index)); | |
224 | assert_eq!(comdat_sections.next(), None); | |
225 | } |