1 use object::read::elf::{FileHeader, SectionHeader};
2 use object::read::{Object, ObjectSymbol};
3 use object::{
4 elf, read, write, Architecture, BinaryFormat, 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 header = elf::FileHeader64::parse(bytes).unwrap();
188 let endian: LittleEndian = header.endian().unwrap();
189 let sections = header.sections(endian, bytes).unwrap();
190
191 let section = sections.section(1).unwrap();
192 assert_eq!(sections.section_name(endian, section).unwrap(), b".note4");
193 assert_eq!(section.sh_addralign(endian), 4);
194 let mut notes = section.notes(endian, bytes).unwrap().unwrap();
195 let note = notes.next().unwrap().unwrap();
196 assert_eq!(note.name(), b"name1");
197 assert_eq!(note.desc(), b"descriptor\0");
198 assert_eq!(note.n_type(endian), 1);
199 let note = notes.next().unwrap().unwrap();
200 assert_eq!(note.name(), b"name2");
201 assert_eq!(note.desc(), b"descriptor\0");
202 assert_eq!(note.n_type(endian), 2);
203 assert!(notes.next().unwrap().is_none());
204
205 let section = sections.section(2).unwrap();
206 assert_eq!(sections.section_name(endian, section).unwrap(), b".note8");
207 assert_eq!(section.sh_addralign(endian), 8);
208 let mut notes = section.notes(endian, bytes).unwrap().unwrap();
209 let note = notes.next().unwrap().unwrap();
210 assert_eq!(note.name(), b"name1");
211 assert_eq!(note.desc(), b"descriptor\0");
212 assert_eq!(note.n_type(endian), 1);
213 let note = notes.next().unwrap().unwrap();
214 assert_eq!(note.name(), b"abc");
215 assert_eq!(note.desc(), b"descriptor\0");
216 assert_eq!(note.n_type(endian), 2);
217 assert!(notes.next().unwrap().is_none());
218 }
219