]> git.proxmox.com Git - rustc.git/blob - vendor/object-0.20.0/src/read/traits.rs
New upstream version 1.49.0+dfsg1
[rustc.git] / vendor / object-0.20.0 / src / read / traits.rs
1 use alloc::borrow::Cow;
2
3 use crate::read::{
4 self, Architecture, CompressedData, FileFlags, Relocation, Result, SectionFlags, SectionIndex,
5 SectionKind, Symbol, SymbolIndex, SymbolMap,
6 };
7 use crate::Endianness;
8
9 /// An object file.
10 pub trait Object<'data, 'file>: read::private::Sealed {
11 /// A segment in the object file.
12 type Segment: ObjectSegment<'data>;
13
14 /// An iterator over the segments in the object file.
15 type SegmentIterator: Iterator<Item = Self::Segment>;
16
17 /// A section in the object file.
18 type Section: ObjectSection<'data>;
19
20 /// An iterator over the sections in the object file.
21 type SectionIterator: Iterator<Item = Self::Section>;
22
23 /// An iterator over the symbols in the object file.
24 type SymbolIterator: Iterator<Item = (SymbolIndex, Symbol<'data>)>;
25
26 /// Get the architecture type of the file.
27 fn architecture(&self) -> Architecture;
28
29 /// Get the endianness of the file.
30 #[inline]
31 fn endianness(&self) -> Endianness {
32 if self.is_little_endian() {
33 Endianness::Little
34 } else {
35 Endianness::Big
36 }
37 }
38
39 /// Return true if the file is little endian, false if it is big endian.
40 fn is_little_endian(&self) -> bool;
41
42 /// Return true if the file can contain 64-bit addresses.
43 fn is_64(&self) -> bool;
44
45 /// Get an iterator over the segments in the file.
46 fn segments(&'file self) -> Self::SegmentIterator;
47
48 /// Get the entry point address of the binary
49 fn entry(&'file self) -> u64;
50
51 /// Get the section named `section_name`, if such a section exists.
52 ///
53 /// If `section_name` starts with a '.' then it is treated as a system section name,
54 /// and is compared using the conventions specific to the object file format. This
55 /// includes:
56 /// - if ".text" is requested for a Mach-O object file, then the actual
57 /// section name that is searched for is "__text".
58 /// - if ".debug_info" is requested for an ELF object file, then
59 /// ".zdebug_info" may be returned (and similarly for other debug sections).
60 ///
61 /// For some object files, multiple segments may contain sections with the same
62 /// name. In this case, the first matching section will be used.
63 ///
64 /// This method skips over sections with invalid names.
65 fn section_by_name(&'file self, section_name: &str) -> Option<Self::Section>;
66
67 /// Get the section at the given index.
68 ///
69 /// The meaning of the index depends on the object file.
70 ///
71 /// For some object files, this requires iterating through all sections.
72 ///
73 /// Returns an error if the index is invalid.
74 fn section_by_index(&'file self, index: SectionIndex) -> Result<Self::Section>;
75
76 /// Get an iterator over the sections in the file.
77 fn sections(&'file self) -> Self::SectionIterator;
78
79 /// Get the debugging symbol at the given index.
80 ///
81 /// The meaning of the index depends on the object file.
82 ///
83 /// Returns an error if the index is invalid.
84 fn symbol_by_index(&self, index: SymbolIndex) -> Result<Symbol<'data>>;
85
86 /// Get an iterator over the debugging symbols in the file.
87 ///
88 /// This may skip over symbols that are malformed or unsupported.
89 fn symbols(&'file self) -> Self::SymbolIterator;
90
91 /// Get the data for the given symbol.
92 ///
93 /// This may iterate over segments.
94 ///
95 /// Returns `Ok(None)` for undefined symbols or if the data could not be found.
96 fn symbol_data(&'file self, symbol: &Symbol<'data>) -> Result<Option<&'data [u8]>> {
97 if symbol.is_undefined() {
98 return Ok(None);
99 }
100 let address = symbol.address();
101 let size = symbol.size();
102 if let Some(index) = symbol.section_index() {
103 let section = self.section_by_index(index)?;
104 section.data_range(address, size)
105 } else {
106 for segment in self.segments() {
107 if let Some(data) = segment.data_range(address, size)? {
108 return Ok(Some(data));
109 }
110 }
111 Ok(None)
112 }
113 }
114
115 /// Get an iterator over the dynamic linking symbols in the file.
116 ///
117 /// This may skip over symbols that are malformed or unsupported.
118 fn dynamic_symbols(&'file self) -> Self::SymbolIterator;
119
120 /// Construct a map from addresses to symbols.
121 fn symbol_map(&self) -> SymbolMap<'data>;
122
123 /// Return true if the file contains debug information sections, false if not.
124 fn has_debug_symbols(&self) -> bool;
125
126 /// The UUID from a Mach-O `LC_UUID` load command.
127 #[inline]
128 fn mach_uuid(&self) -> Result<Option<[u8; 16]>> {
129 Ok(None)
130 }
131
132 /// The build ID from an ELF `NT_GNU_BUILD_ID` note.
133 #[inline]
134 fn build_id(&self) -> Result<Option<&'data [u8]>> {
135 Ok(None)
136 }
137
138 /// The filename and CRC from a `.gnu_debuglink` section.
139 #[inline]
140 fn gnu_debuglink(&self) -> Result<Option<(&'data [u8], u32)>> {
141 Ok(None)
142 }
143
144 /// File flags that are specific to each file format.
145 fn flags(&self) -> FileFlags;
146 }
147
148 /// A loadable segment defined in an object file.
149 ///
150 /// For ELF, this is a program header with type `PT_LOAD`.
151 /// For Mach-O, this is a load command with type `LC_SEGMENT` or `LC_SEGMENT_64`.
152 pub trait ObjectSegment<'data>: read::private::Sealed {
153 /// Returns the virtual address of the segment.
154 fn address(&self) -> u64;
155
156 /// Returns the size of the segment in memory.
157 fn size(&self) -> u64;
158
159 /// Returns the alignment of the segment in memory.
160 fn align(&self) -> u64;
161
162 /// Returns the offset and size of the segment in the file.
163 fn file_range(&self) -> (u64, u64);
164
165 /// Returns a reference to the file contents of the segment.
166 ///
167 /// The length of this data may be different from the size of the
168 /// segment in memory.
169 fn data(&self) -> Result<&'data [u8]>;
170
171 /// Return the segment data in the given range.
172 ///
173 /// Returns `Ok(None)` if the segment does not contain the given range.
174 fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>>;
175
176 /// Returns the name of the segment.
177 fn name(&self) -> Result<Option<&str>>;
178 }
179
180 /// A section defined in an object file.
181 pub trait ObjectSection<'data>: read::private::Sealed {
182 /// An iterator over the relocations for a section.
183 ///
184 /// The first field in the item tuple is the section offset
185 /// that the relocation applies to.
186 type RelocationIterator: Iterator<Item = (u64, Relocation)>;
187
188 /// Returns the section index.
189 fn index(&self) -> SectionIndex;
190
191 /// Returns the address of the section.
192 fn address(&self) -> u64;
193
194 /// Returns the size of the section in memory.
195 fn size(&self) -> u64;
196
197 /// Returns the alignment of the section in memory.
198 fn align(&self) -> u64;
199
200 /// Returns offset and size of on-disk segment (if any).
201 fn file_range(&self) -> Option<(u64, u64)>;
202
203 /// Returns the raw contents of the section.
204 ///
205 /// The length of this data may be different from the size of the
206 /// section in memory.
207 ///
208 /// This does not do any decompression.
209 fn data(&self) -> Result<&'data [u8]>;
210
211 /// Return the raw contents of the section data in the given range.
212 ///
213 /// This does not do any decompression.
214 ///
215 /// Returns `Ok(None)` if the section does not contain the given range.
216 fn data_range(&self, address: u64, size: u64) -> Result<Option<&'data [u8]>>;
217
218 /// Returns the potentially compressed contents of the section,
219 /// along with information about the compression.
220 fn compressed_data(&self) -> Result<CompressedData<'data>>;
221
222 /// Returns the uncompressed contents of the section.
223 ///
224 /// The length of this data may be different from the size of the
225 /// section in memory.
226 ///
227 /// If no compression is detected, then returns the data unchanged.
228 /// Returns `Err` if decompression fails.
229 fn uncompressed_data(&self) -> Result<Cow<'data, [u8]>> {
230 self.compressed_data()?.decompress()
231 }
232
233 /// Returns the name of the section.
234 fn name(&self) -> Result<&str>;
235
236 /// Returns the name of the segment for this section.
237 fn segment_name(&self) -> Result<Option<&str>>;
238
239 /// Return the kind of this section.
240 fn kind(&self) -> SectionKind;
241
242 /// Get the relocations for this section.
243 fn relocations(&self) -> Self::RelocationIterator;
244
245 /// Section flags that are specific to each file format.
246 fn flags(&self) -> SectionFlags;
247 }