1 use object::read::elf::{FileHeader, SectionHeader};
2 use object::read::{Object, ObjectSymbol};
3 use object::{
4     elf, read, write, Architecture, BinaryFormat, Bytes, Endianness, LittleEndian, SectionIndex,
5     SectionKind, SymbolFlags, SymbolKind, SymbolScope, SymbolSection, U32,
6 };
7 use std::io::Write;
8 
9 #[test]
symtab_shndx()10 fn symtab_shndx() {
11     let mut object =
12         write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
13 
14     for i in 0..0x10000 {
15         let name = format!("func{}", i).into_bytes();
16         let (section, offset) =
17             object.add_subsection(write::StandardSection::Text, &name, &[0xcc], 1);
18         object.add_symbol(write::Symbol {
19             name,
20             value: offset,
21             size: 1,
22             kind: SymbolKind::Text,
23             scope: SymbolScope::Linkage,
24             weak: false,
25             section: write::SymbolSection::Section(section),
26             flags: SymbolFlags::None,
27         });
28     }
29     let bytes = object.write().unwrap();
30 
31     //std::fs::write(&"symtab_shndx.o", &bytes).unwrap();
32 
33     let object = read::File::parse(&bytes).unwrap();
34     assert_eq!(object.format(), BinaryFormat::Elf);
35     assert_eq!(object.architecture(), Architecture::X86_64);
36 
37     for symbol in object.symbols().skip(1) {
38         assert_eq!(
39             symbol.section(),
40             SymbolSection::Section(SectionIndex(symbol.index().0))
41         );
42     }
43 }
44 
45 #[cfg(feature = "compression")]
46 #[test]
compression_zlib()47 fn compression_zlib() {
48     use object::read::ObjectSection;
49     use object::LittleEndian as LE;
50 
51     let data = b"test data data data";
52     let len = data.len() as u64;
53 
54     let mut ch = object::elf::CompressionHeader64::<LE>::default();
55     ch.ch_type.set(LE, object::elf::ELFCOMPRESS_ZLIB);
56     ch.ch_size.set(LE, len);
57     ch.ch_addralign.set(LE, 1);
58 
59     let mut buf = Vec::new();
60     buf.write(object::bytes_of(&ch)).unwrap();
61     let mut encoder = flate2::write::ZlibEncoder::new(buf, flate2::Compression::default());
62     encoder.write_all(data).unwrap();
63     let compressed = encoder.finish().unwrap();
64 
65     let mut object =
66         write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
67     let section = object.add_section(
68         Vec::new(),
69         b".debug_info".to_vec(),
70         object::SectionKind::Other,
71     );
72     object.section_mut(section).set_data(compressed, 1);
73     object.section_mut(section).flags = object::SectionFlags::Elf {
74         sh_flags: object::elf::SHF_COMPRESSED.into(),
75     };
76     let bytes = object.write().unwrap();
77 
78     //std::fs::write(&"compression.o", &bytes).unwrap();
79 
80     let object = read::File::parse(&bytes).unwrap();
81     assert_eq!(object.format(), BinaryFormat::Elf);
82     assert_eq!(object.architecture(), Architecture::X86_64);
83 
84     let section = object.section_by_name(".debug_info").unwrap();
85     let uncompressed = section.uncompressed_data().unwrap();
86     assert_eq!(data, &*uncompressed);
87 }
88 
89 #[cfg(feature = "compression")]
90 #[test]
compression_gnu()91 fn compression_gnu() {
92     use object::read::ObjectSection;
93     use std::io::Write;
94 
95     let data = b"test data data data";
96     let len = data.len() as u32;
97 
98     let mut buf = Vec::new();
99     buf.write_all(b"ZLIB\0\0\0\0").unwrap();
100     buf.write_all(&len.to_be_bytes()).unwrap();
101     let mut encoder = flate2::write::ZlibEncoder::new(buf, flate2::Compression::default());
102     encoder.write_all(data).unwrap();
103     let compressed = encoder.finish().unwrap();
104 
105     let mut object =
106         write::Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
107     let section = object.add_section(
108         Vec::new(),
109         b".zdebug_info".to_vec(),
110         object::SectionKind::Other,
111     );
112     object.section_mut(section).set_data(compressed, 1);
113     let bytes = object.write().unwrap();
114 
115     //std::fs::write(&"compression.o", &bytes).unwrap();
116 
117     let object = read::File::parse(&bytes).unwrap();
118     assert_eq!(object.format(), BinaryFormat::Elf);
119     assert_eq!(object.architecture(), Architecture::X86_64);
120 
121     let section = object.section_by_name(".zdebug_info").unwrap();
122     let uncompressed = section.uncompressed_data().unwrap();
123     assert_eq!(data, &*uncompressed);
124 }
125 
126 #[test]
note()127 fn note() {
128     let endian = Endianness::Little;
129     let mut object = write::Object::new(BinaryFormat::Elf, Architecture::X86_64, endian);
130 
131     // Add note section with align = 4.
132     let mut buffer = Vec::new();
133 
134     buffer
135         .write(object::bytes_of(&elf::NoteHeader32 {
136             n_namesz: U32::new(endian, 6),
137             n_descsz: U32::new(endian, 11),
138             n_type: U32::new(endian, 1),
139         }))
140         .unwrap();
141     buffer.write(b"name1\0\0\0").unwrap();
142     buffer.write(b"descriptor\0\0").unwrap();
143 
144     buffer
145         .write(object::bytes_of(&elf::NoteHeader32 {
146             n_namesz: U32::new(endian, 6),
147             n_descsz: U32::new(endian, 11),
148             n_type: U32::new(endian, 2),
149         }))
150         .unwrap();
151     buffer.write(b"name2\0\0\0").unwrap();
152     buffer.write(b"descriptor\0\0").unwrap();
153 
154     let section = object.add_section(Vec::new(), b".note4".to_vec(), SectionKind::Note);
155     object.section_mut(section).set_data(buffer, 4);
156 
157     // Add note section with align = 8.
158     let mut buffer = Vec::new();
159 
160     buffer
161         .write(object::bytes_of(&elf::NoteHeader32 {
162             n_namesz: U32::new(endian, 6),
163             n_descsz: U32::new(endian, 11),
164             n_type: U32::new(endian, 1),
165         }))
166         .unwrap();
167     buffer.write(b"name1\0\0\0\0\0\0\0").unwrap();
168     buffer.write(b"descriptor\0\0\0\0\0\0").unwrap();
169 
170     buffer
171         .write(object::bytes_of(&elf::NoteHeader32 {
172             n_namesz: U32::new(endian, 4),
173             n_descsz: U32::new(endian, 11),
174             n_type: U32::new(endian, 2),
175         }))
176         .unwrap();
177     buffer.write(b"abc\0").unwrap();
178     buffer.write(b"descriptor\0\0\0\0\0\0").unwrap();
179 
180     let section = object.add_section(Vec::new(), b".note8".to_vec(), SectionKind::Note);
181     object.section_mut(section).set_data(buffer, 8);
182 
183     let bytes = object.write().unwrap();
184 
185     //std::fs::write(&"note.o", &bytes).unwrap();
186 
187     let bytes = Bytes(&bytes);
188     let header = elf::FileHeader64::parse(bytes).unwrap();
189     let endian: LittleEndian = header.endian().unwrap();
190     let sections = header.sections(endian, bytes).unwrap();
191 
192     let section = sections.section(1).unwrap();
193     assert_eq!(sections.section_name(endian, section).unwrap(), b".note4");
194     assert_eq!(section.sh_addralign(endian), 4);
195     let mut notes = section.notes(endian, bytes).unwrap().unwrap();
196     let note = notes.next().unwrap().unwrap();
197     assert_eq!(note.name(), b"name1");
198     assert_eq!(note.desc(), b"descriptor\0");
199     assert_eq!(note.n_type(endian), 1);
200     let note = notes.next().unwrap().unwrap();
201     assert_eq!(note.name(), b"name2");
202     assert_eq!(note.desc(), b"descriptor\0");
203     assert_eq!(note.n_type(endian), 2);
204     assert!(notes.next().unwrap().is_none());
205 
206     let section = sections.section(2).unwrap();
207     assert_eq!(sections.section_name(endian, section).unwrap(), b".note8");
208     assert_eq!(section.sh_addralign(endian), 8);
209     let mut notes = section.notes(endian, bytes).unwrap().unwrap();
210     let note = notes.next().unwrap().unwrap();
211     assert_eq!(note.name(), b"name1");
212     assert_eq!(note.desc(), b"descriptor\0");
213     assert_eq!(note.n_type(endian), 1);
214     let note = notes.next().unwrap().unwrap();
215     assert_eq!(note.name(), b"abc");
216     assert_eq!(note.desc(), b"descriptor\0");
217     assert_eq!(note.n_type(endian), 2);
218     assert!(notes.next().unwrap().is_none());
219 }
220