]> git.proxmox.com Git - rustc.git/blob - vendor/object-0.26.2/src/read/traits.rs
New upstream version 1.66.0+dfsg1
[rustc.git] / vendor / object-0.26.2 / src / read / traits.rs
1 use alloc::borrow::Cow;
2 use alloc::vec::Vec;
3
4 use crate::read::{
5 self, Architecture, CodeView, ComdatKind, CompressedData, CompressedFileRange, Export,
6 FileFlags, Import, ObjectMap, Relocation, Result, SectionFlags, SectionIndex, SectionKind,
7 SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapName, SymbolScope, SymbolSection,
8 };
9 use crate::Endianness;
10
11 /// An object file.
12 pub trait Object<'data: 'file, 'file>: read::private::Sealed {
13 /// A segment in the object file.
14 type Segment: ObjectSegment<'data>;
15
16 /// An iterator over the segments in the object file.
17 type SegmentIterator: Iterator<Item = Self::Segment>;
18
19 /// A section in the object file.
20 type Section: ObjectSection<'data>;
21
22 /// An iterator over the sections in the object file.
23 type SectionIterator: Iterator<Item = Self::Section>;
24
25 /// A COMDAT section group in the object file.
26 type Comdat: ObjectComdat<'data>;
27
28 /// An iterator over the COMDAT section groups in the object file.
29 type ComdatIterator: Iterator<Item = Self::Comdat>;
30
31 /// A symbol in the object file.
32 type Symbol: ObjectSymbol<'data>;
33
34 /// An iterator over symbols in the object file.
35 type SymbolIterator: Iterator<Item = Self::Symbol>;
36
37 /// A symbol table in the object file.
38 type SymbolTable: ObjectSymbolTable<
39 'data,
40 Symbol = Self::Symbol,
41 SymbolIterator = Self::SymbolIterator,
42 >;
43
44 /// An iterator over dynamic relocations in the file.
45 ///
46 /// The first field in the item tuple is the address
47 /// that the relocation applies to.
48 type DynamicRelocationIterator: Iterator<Item = (u64, Relocation)>;
49
50 /// Get the architecture type of the file.
51 fn architecture(&self) -> Architecture;
52
53 /// Get the endianness of the file.
54 #[inline]
55 fn endianness(&self) -> Endianness {
56 if self.is_little_endian() {
57 Endianness::Little
58 } else {
59 Endianness::Big
60 }
61 }
62
63 /// Return true if the file is little endian, false if it is big endian.
64 fn is_little_endian(&self) -> bool;
65
66 /// Return true if the file can contain 64-bit addresses.
67 fn is_64(&self) -> bool;
68
69 /// Get an iterator over the segments in the file.
70 fn segments(&'file self) -> Self::SegmentIterator;
71
72 /// Get the section named `section_name`, if such a section exists.
73 ///
74 /// If `section_name` starts with a '.' then it is treated as a system section name,
75 /// and is compared using the conventions specific to the object file format. This
76 /// includes:
77 /// - if ".debug_str_offsets" is requested for a Mach-O object file, then the actual
78 /// section name that is searched for is "__debug_str_offs".
79 /// - if ".debug_info" is requested for an ELF object file, then
80 /// ".zdebug_info" may be returned (and similarly for other debug sections).
81 ///
82 /// For some object files, multiple segments may contain sections with the same
83 /// name. In this case, the first matching section will be used.
84 ///
85 /// This method skips over sections with invalid names.
86 fn section_by_name(&'file self, section_name: &str) -> Option<Self::Section>;
87
88 /// Get the section at the given index.
89 ///
90 /// The meaning of the index depends on the object file.
91 ///
92 /// For some object files, this requires iterating through all sections.
93 ///
94 /// Returns an error if the index is invalid.
95 fn section_by_index(&'file self, index: SectionIndex) -> Result<Self::Section>;
96
97 /// Get an iterator over the sections in the file.
98 fn sections(&'file self) -> Self::SectionIterator;
99
100 /// Get an iterator over the COMDAT section groups in the file.
101 fn comdats(&'file self) -> Self::ComdatIterator;
102
103 /// Get the symbol table, if any.
104 fn symbol_table(&'file self) -> Option<Self::SymbolTable>;
105
106 /// Get the debugging symbol at the given index.
107 ///
108 /// The meaning of the index depends on the object file.
109 ///
110 /// Returns an error if the index is invalid.
111 fn symbol_by_index(&'file self, index: SymbolIndex) -> Result<Self::Symbol>;
112
113 /// Get an iterator over the debugging symbols in the file.
114 ///
115 /// This may skip over symbols that are malformed or unsupported.
116 ///
117 /// For Mach-O files, this does not include STAB entries.
118 fn symbols(&'file self) -> Self::SymbolIterator;
119
120 /// Get the dynamic linking symbol table, if any.
121 ///
122 /// Only ELF has a separate dynamic linking symbol table.
123 fn dynamic_symbol_table(&'file self) -> Option<Self::SymbolTable>;
124
125 /// Get an iterator over the dynamic linking symbols in the file.
126 ///
127 /// This may skip over symbols that are malformed or unsupported.
128 ///
129 /// Only ELF has separate dynamic linking symbols.
130 /// Other file formats will return an empty iterator.
131 fn dynamic_symbols(&'file self) -> Self::SymbolIterator;
132
133 /// Get the dynamic relocations for this file.
134 ///
135 /// Symbol indices in these relocations refer to the dynamic symbol table.
136 ///
137 /// Only ELF has dynamic relocations.
138 fn dynamic_relocations(&'file self) -> Option<Self::DynamicRelocationIterator>;
139
140 /// Construct a map from addresses to symbol names.
141 ///
142 /// The map will only contain defined text and data symbols.
143 /// The dynamic symbol table will only be used if there are no debugging symbols.
144 fn symbol_map(&'file self) -> SymbolMap<SymbolMapName<'data>> {
145 let mut symbols = Vec::new();
146 if let Some(table) = self.symbol_table().or_else(|| self.dynamic_symbol_table()) {
147 for symbol in table.symbols() {
148 if !symbol.is_definition() {
149 continue;
150 }
151 if let Ok(name) = symbol.name() {
152 symbols.push(SymbolMapName::new(symbol.address(), name));
153 }
154 }
155 }
156 SymbolMap::new(symbols)
157 }
158
159 /// Construct a map from addresses to symbol names and object file names.
160 ///
161 /// This is derived from Mach-O STAB entries.
162 fn object_map(&'file self) -> ObjectMap<'data> {
163 ObjectMap::default()
164 }
165
166 /// Get the imported symbols.
167 fn imports(&self) -> Result<Vec<Import<'data>>>;
168
169 /// Get the exported symbols.
170 fn exports(&self) -> Result<Vec<Export<'data>>>;
171
172 /// Return true if the file contains debug information sections, false if not.
173 fn has_debug_symbols(&self) -> bool;
174
175 /// The UUID from a Mach-O `LC_UUID` load command.
176 #[inline]
177 fn mach_uuid(&self) -> Result<Option<[u8; 16]>> {
178 Ok(None)
179 }
180
181 /// The build ID from an ELF `NT_GNU_BUILD_ID` note.
182 #[inline]
183 fn build_id(&self) -> Result<Option<&'data [u8]>> {
184 Ok(None)
185 }
186
187 /// The filename and CRC from a `.gnu_debuglink` section.
188 #[inline]
189 fn gnu_debuglink(&self) -> Result<Option<(&'data [u8], u32)>> {
190 Ok(None)
191 }
192
193 /// The filename and build ID from a `.gnu_debugaltlink` section.
194 #[inline]
195 fn gnu_debugaltlink(&self) -> Result<Option<(&'data [u8], &'data [u8])>> {
196 Ok(None)
197 }
198
199 /// The filename and GUID from the PE CodeView section
200 #[inline]
201 fn pdb_info(&self) -> Result<Option<CodeView>> {
202 Ok(None)
203 }
204
205 /// Get the base address used for relative virtual addresses.
206 ///
207 /// Currently this is only non-zero for PE.
208 fn relative_address_base(&'file self) -> u64;
209
210 /// Get the virtual address of the entry point of the binary
211 fn entry(&'file self) -> u64;
212
213 /// File flags that are specific to each file format.
214 fn flags(&self) -> FileFlags;
215 }
216
217 /// A loadable segment defined in an object file.
218 ///
219 /// For ELF, this is a program header with type `PT_LOAD`.
220 /// For Mach-O, this is a load command with type `LC_SEGMENT` or `LC_SEGMENT_64`.
221 pub trait ObjectSegment<'data>: read::private::Sealed {
222 /// Returns the virtual address of the segment.
223 fn address(&self) -> u64;
224
225 /// Returns the size of the segment in memory.
226 fn size(&self) -> u64;
227
228 /// Returns the alignment of the segment in memory.
229 fn align(&self) -> u64;
230
231 /// Returns the offset and size of the segment in the file.
232 fn file_range(&self) -> (u64, u64);
233
234 /// Returns a reference to the file contents of the segment.
235 ///
236 /// The length of this data may be different from the size of the
237 /// segment in memory.
238 fn data(&self) -> Result<&'data [u8]>;
239
240 /// Return the segment data in the given range.
241 ///
242 /// Returns `Ok(None)` if the segment does not contain the given range.
243 fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>>;
244
245 /// Returns the name of the segment.
246 fn name(&self) -> Result<Option<&str>>;
247 }
248
249 /// A section defined in an object file.
250 pub trait ObjectSection<'data>: read::private::Sealed {
251 /// An iterator over the relocations for a section.
252 ///
253 /// The first field in the item tuple is the section offset
254 /// that the relocation applies to.
255 type RelocationIterator: Iterator<Item = (u64, Relocation)>;
256
257 /// Returns the section index.
258 fn index(&self) -> SectionIndex;
259
260 /// Returns the address of the section.
261 fn address(&self) -> u64;
262
263 /// Returns the size of the section in memory.
264 fn size(&self) -> u64;
265
266 /// Returns the alignment of the section in memory.
267 fn align(&self) -> u64;
268
269 /// Returns offset and size of on-disk segment (if any).
270 fn file_range(&self) -> Option<(u64, u64)>;
271
272 /// Returns the raw contents of the section.
273 ///
274 /// The length of this data may be different from the size of the
275 /// section in memory.
276 ///
277 /// This does not do any decompression.
278 fn data(&self) -> Result<&'data [u8]>;
279
280 /// Return the raw contents of the section data in the given range.
281 ///
282 /// This does not do any decompression.
283 ///
284 /// Returns `Ok(None)` if the section does not contain the given range.
285 fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>>;
286
287 /// Returns the potentially compressed file range of the section,
288 /// along with information about the compression.
289 fn compressed_file_range(&self) -> Result<CompressedFileRange>;
290
291 /// Returns the potentially compressed contents of the section,
292 /// along with information about the compression.
293 fn compressed_data(&self) -> Result<CompressedData<'data>>;
294
295 /// Returns the uncompressed contents of the section.
296 ///
297 /// The length of this data may be different from the size of the
298 /// section in memory.
299 ///
300 /// If no compression is detected, then returns the data unchanged.
301 /// Returns `Err` if decompression fails.
302 fn uncompressed_data(&self) -> Result<Cow<'data, [u8]>> {
303 self.compressed_data()?.decompress()
304 }
305
306 /// Returns the name of the section.
307 fn name(&self) -> Result<&str>;
308
309 /// Returns the name of the segment for this section.
310 fn segment_name(&self) -> Result<Option<&str>>;
311
312 /// Return the kind of this section.
313 fn kind(&self) -> SectionKind;
314
315 /// Get the relocations for this section.
316 fn relocations(&self) -> Self::RelocationIterator;
317
318 /// Section flags that are specific to each file format.
319 fn flags(&self) -> SectionFlags;
320 }
321
322 /// A COMDAT section group defined in an object file.
323 pub trait ObjectComdat<'data>: read::private::Sealed {
324 /// An iterator over the sections in the object file.
325 type SectionIterator: Iterator<Item = SectionIndex>;
326
327 /// Returns the COMDAT selection kind.
328 fn kind(&self) -> ComdatKind;
329
330 /// Returns the index of the symbol used for the name of COMDAT section group.
331 fn symbol(&self) -> SymbolIndex;
332
333 /// Returns the name of the COMDAT section group.
334 fn name(&self) -> Result<&str>;
335
336 /// Get the sections in this section group.
337 fn sections(&self) -> Self::SectionIterator;
338 }
339
340 /// A symbol table.
341 pub trait ObjectSymbolTable<'data>: read::private::Sealed {
342 /// A symbol table entry.
343 type Symbol: ObjectSymbol<'data>;
344
345 /// An iterator over the symbols in a symbol table.
346 type SymbolIterator: Iterator<Item = Self::Symbol>;
347
348 /// Get an iterator over the symbols in the table.
349 ///
350 /// This may skip over symbols that are malformed or unsupported.
351 fn symbols(&self) -> Self::SymbolIterator;
352
353 /// Get the symbol at the given index.
354 ///
355 /// The meaning of the index depends on the object file.
356 ///
357 /// Returns an error if the index is invalid.
358 fn symbol_by_index(&self, index: SymbolIndex) -> Result<Self::Symbol>;
359 }
360
361 /// A symbol table entry.
362 pub trait ObjectSymbol<'data>: read::private::Sealed {
363 /// The index of the symbol.
364 fn index(&self) -> SymbolIndex;
365
366 /// The name of the symbol.
367 fn name(&self) -> Result<&'data str>;
368
369 /// The address of the symbol. May be zero if the address is unknown.
370 fn address(&self) -> u64;
371
372 /// The size of the symbol. May be zero if the size is unknown.
373 fn size(&self) -> u64;
374
375 /// Return the kind of this symbol.
376 fn kind(&self) -> SymbolKind;
377
378 /// Returns the section where the symbol is defined.
379 fn section(&self) -> SymbolSection;
380
381 /// Returns the section index for the section containing this symbol.
382 ///
383 /// May return `None` if the symbol is not defined in a section.
384 fn section_index(&self) -> Option<SectionIndex> {
385 self.section().index()
386 }
387
388 /// Return true if the symbol is undefined.
389 fn is_undefined(&self) -> bool;
390
391 /// Return true if the symbol is a definition of a function or data object
392 /// that has a known address.
393 fn is_definition(&self) -> bool;
394
395 /// Return true if the symbol is common data.
396 ///
397 /// Note: does not check for `SymbolSection::Section` with `SectionKind::Common`.
398 fn is_common(&self) -> bool;
399
400 /// Return true if the symbol is weak.
401 fn is_weak(&self) -> bool;
402
403 /// Returns the symbol scope.
404 fn scope(&self) -> SymbolScope;
405
406 /// Return true if the symbol visible outside of the compilation unit.
407 ///
408 /// This treats `SymbolScope::Unknown` as global.
409 fn is_global(&self) -> bool;
410
411 /// Return true if the symbol is only visible within the compilation unit.
412 fn is_local(&self) -> bool;
413
414 /// Symbol flags that are specific to each file format.
415 fn flags(&self) -> SymbolFlags<SectionIndex>;
416 }
417
418 /// An iterator for files that don't have dynamic relocations.
419 #[derive(Debug)]
420 pub struct NoDynamicRelocationIterator;
421
422 impl Iterator for NoDynamicRelocationIterator {
423 type Item = (u64, Relocation);
424
425 #[inline]
426 fn next(&mut self) -> Option<Self::Item> {
427 None
428 }
429 }