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]
coff_x86_64_comdat()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(), "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]
elf_x86_64_common()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(), "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 }
226