1use std::error;
62use std::fmt;
63use std::result;
64
65use crate::constants;
66
67mod endian_vec;
68pub use self::endian_vec::*;
69
70mod writer;
71pub use self::writer::*;
72
73mod relocate;
74pub use self::relocate::*;
75
76#[macro_use]
77mod section;
78pub use self::section::*;
79
80macro_rules! define_id {
81 ($name:ident, $docs:expr) => {
82 #[doc=$docs]
83 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
84 pub struct $name {
85 base_id: BaseId,
86 index: usize,
87 }
88
89 impl $name {
90 #[inline]
91 fn new(base_id: BaseId, index: usize) -> Self {
92 $name { base_id, index }
93 }
94 }
95 };
96}
97
98macro_rules! define_offsets {
99 ($offsets:ident: $id:ident => $offset:ident, $off_doc:expr) => {
100 #[doc=$off_doc]
101 #[derive(Debug)]
102 pub struct $offsets {
103 base_id: BaseId,
104 offsets: Vec<$offset>,
106 }
107
108 impl $offsets {
109 #[inline]
111 pub fn none() -> Self {
112 $offsets {
113 base_id: BaseId::default(),
114 offsets: Vec::new(),
115 }
116 }
117
118 #[inline]
124 pub fn get(&self, id: $id) -> $offset {
125 debug_assert_eq!(self.base_id, id.base_id);
126 self.offsets[id.index]
127 }
128
129 #[inline]
131 pub fn count(&self) -> usize {
132 self.offsets.len()
133 }
134 }
135 };
136}
137
138mod abbrev;
139pub use self::abbrev::*;
140
141mod cfi;
142pub use self::cfi::*;
143
144mod dwarf;
145pub use self::dwarf::*;
146
147mod line;
148pub use self::line::*;
149
150mod loc;
151pub use self::loc::*;
152
153mod op;
154pub use self::op::*;
155
156mod range;
157pub use self::range::*;
158
159mod str;
160pub use self::str::*;
161
162mod unit;
163pub use self::unit::*;
164
165#[derive(Debug, Clone, Copy, PartialEq, Eq)]
167pub enum Error {
168 OffsetOutOfBounds,
170 LengthOutOfBounds,
172 InvalidAttributeValue,
174 ValueTooLarge,
176 UnsupportedWordSize(u8),
178 UnsupportedVersion(u16),
180 InitialLengthOverflow,
182 InvalidAddress,
184 InvalidReference,
186 NeedVersion(u16),
188 LineStringFormMismatch,
190 InvalidRange,
192 IncompatibleLineProgramEncoding,
194 InvalidFrameCodeOffset(u32),
196 InvalidFrameDataOffset(i32),
198 UnsupportedPointerEncoding(constants::DwEhPe),
200 UnsupportedCfiExpressionReference,
202 UnsupportedExpressionForwardReference,
204}
205
206impl fmt::Display for Error {
207 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> result::Result<(), fmt::Error> {
208 match *self {
209 Error::OffsetOutOfBounds => write!(f, "The given offset is out of bounds."),
210 Error::LengthOutOfBounds => write!(f, "The given length is out of bounds."),
211 Error::InvalidAttributeValue => {
212 write!(f, "The attribute value is an invalid for writing.")
213 }
214 Error::ValueTooLarge => write!(f, "The value is too large for the encoding form."),
215 Error::UnsupportedWordSize(size) => write!(f, "Unsupported word size: {}", size),
216 Error::UnsupportedVersion(version) => {
217 write!(f, "Unsupported DWARF version: {}", version)
218 }
219 Error::InitialLengthOverflow => write!(
220 f,
221 "The unit length is too large for the requested DWARF format."
222 ),
223 Error::InvalidAddress => write!(f, "The address is invalid."),
224 Error::InvalidReference => write!(f, "The reference is invalid."),
225 Error::NeedVersion(version) => write!(
226 f,
227 "A requested feature requires a DWARF version {}.",
228 version
229 ),
230 Error::LineStringFormMismatch => {
231 write!(f, "Strings in line number program have mismatched forms.")
232 }
233 Error::InvalidRange => write!(f, "The range is empty or otherwise invalid."),
234 Error::IncompatibleLineProgramEncoding => write!(
235 f,
236 "The line number program encoding is incompatible with the unit encoding."
237 ),
238 Error::InvalidFrameCodeOffset(offset) => write!(
239 f,
240 "Could not encode code offset ({}) for a frame instruction.",
241 offset,
242 ),
243 Error::InvalidFrameDataOffset(offset) => write!(
244 f,
245 "Could not encode data offset ({}) for a frame instruction.",
246 offset,
247 ),
248 Error::UnsupportedPointerEncoding(eh_pe) => {
249 write!(f, "Unsupported eh_frame pointer encoding ({}).", eh_pe)
250 }
251 Error::UnsupportedCfiExpressionReference => {
252 write!(f, "Unsupported reference in CFI expression.")
253 }
254 Error::UnsupportedExpressionForwardReference => {
255 write!(f, "Unsupported forward reference in expression.")
256 }
257 }
258 }
259}
260
261impl error::Error for Error {}
262
263pub type Result<T> = result::Result<T, Error>;
265
266#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
268pub enum Address {
269 Constant(u64),
271 Symbol {
273 symbol: usize,
278 addend: i64,
282 },
283}
284
285#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
287pub enum Reference {
288 Symbol(usize),
293 Entry(UnitId, UnitEntryId),
297}
298
299#[cfg(not(debug_assertions))]
301type BaseId = ();
302
303#[cfg(debug_assertions)]
304#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
305struct BaseId(usize);
306
307#[cfg(debug_assertions)]
308impl Default for BaseId {
309 fn default() -> Self {
310 use std::sync::atomic;
311 static BASE_ID: atomic::AtomicUsize = atomic::AtomicUsize::new(0);
312 BaseId(BASE_ID.fetch_add(1, atomic::Ordering::Relaxed))
313 }
314}
315
316#[cfg(feature = "read")]
317mod convert {
318 use super::*;
319 use crate::read;
320
321 pub(crate) use super::unit::convert::*;
322
323 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
325 pub enum ConvertError {
326 Read(read::Error),
328 UnsupportedAttributeValue,
330 InvalidAttributeValue,
332 InvalidDebugInfoOffset,
334 InvalidAddress,
336 UnsupportedLineInstruction,
338 UnsupportedLineStringForm,
340 InvalidFileIndex,
342 InvalidDirectoryIndex,
344 InvalidLineBase,
346 InvalidLineRef,
348 InvalidUnitRef,
350 InvalidDebugInfoRef,
352 InvalidRangeRelativeAddress,
354 UnsupportedCfiInstruction,
356 UnsupportedIndirectAddress,
358 UnsupportedOperation,
360 InvalidBranchTarget,
362 UnsupportedUnitType,
364 }
365
366 impl fmt::Display for ConvertError {
367 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> result::Result<(), fmt::Error> {
368 use self::ConvertError::*;
369 match *self {
370 Read(ref e) => e.fmt(f),
371 UnsupportedAttributeValue => {
372 write!(f, "Writing of this attribute value is not implemented yet.")
373 }
374 InvalidAttributeValue => write!(
375 f,
376 "This attribute value is an invalid name/form combination."
377 ),
378 InvalidDebugInfoOffset => write!(
379 f,
380 "A `.debug_info` reference does not refer to a valid entry."
381 ),
382 InvalidAddress => write!(f, "An address could not be converted."),
383 UnsupportedLineInstruction => write!(
384 f,
385 "Writing this line number instruction is not implemented yet."
386 ),
387 UnsupportedLineStringForm => write!(
388 f,
389 "Writing this form of line string is not implemented yet."
390 ),
391 InvalidFileIndex => write!(f, "A `.debug_line` file index is invalid."),
392 InvalidDirectoryIndex => write!(f, "A `.debug_line` directory index is invalid."),
393 InvalidLineBase => write!(f, "A `.debug_line` line base is invalid."),
394 InvalidLineRef => write!(f, "A `.debug_line` reference is invalid."),
395 InvalidUnitRef => write!(f, "A `.debug_info` unit entry reference is invalid."),
396 InvalidDebugInfoRef => write!(f, "A `.debug_info` reference is invalid."),
397 InvalidRangeRelativeAddress => {
398 write!(f, "Invalid relative address in a range list.")
399 }
400 UnsupportedCfiInstruction => {
401 write!(f, "Writing this CFI instruction is not implemented yet.")
402 }
403 UnsupportedIndirectAddress => {
404 write!(f, "Writing indirect pointers is not implemented yet.")
405 }
406 UnsupportedOperation => write!(
407 f,
408 "Writing this expression operation is not implemented yet."
409 ),
410 InvalidBranchTarget => write!(f, "Operation branch target is invalid."),
411 UnsupportedUnitType => write!(f, "Writing this unit type is not supported yet."),
412 }
413 }
414 }
415
416 impl error::Error for ConvertError {}
417
418 impl From<read::Error> for ConvertError {
419 fn from(e: read::Error) -> Self {
420 ConvertError::Read(e)
421 }
422 }
423
424 pub type ConvertResult<T> = result::Result<T, ConvertError>;
426}
427#[cfg(feature = "read")]
428pub use self::convert::*;