1#![deny(missing_docs)]
21#![warn(bare_trait_objects)]
23#![warn(unused_extern_crates)]
24#![allow(clippy::single_match)]
26#![allow(clippy::match_single_binding)]
27#![allow(clippy::too_many_arguments)]
28#![allow(clippy::uninlined_format_args)]
29
30#[macro_use]
31extern crate log;
32
33mod cfi;
34mod file;
35mod function;
36mod location;
37mod namespace;
38mod range;
39mod source;
40mod types;
41mod unit;
42mod variable;
43
44pub use crate::cfi::*;
45pub use crate::file::*;
46pub use crate::function::*;
47pub use crate::location::*;
48pub use crate::namespace::*;
49pub use crate::range::*;
50pub use crate::source::*;
51pub use crate::types::*;
52pub use crate::unit::*;
53pub use crate::variable::*;
54
55use std::borrow::{Borrow, Cow};
56use std::error;
57use std::fmt;
58use std::io;
59use std::result;
60use std::sync::atomic::{AtomicUsize, Ordering};
61
62#[derive(Debug)]
64pub struct Error(pub Cow<'static, str>);
65
66impl error::Error for Error {
67 fn description(&self) -> &str {
68 self.0.borrow()
69 }
70}
71
72impl fmt::Display for Error {
73 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74 write!(f, "{}", self.0)
75 }
76}
77
78impl From<&'static str> for Error {
79 fn from(s: &'static str) -> Error {
80 Error(Cow::Borrowed(s))
81 }
82}
83
84impl From<String> for Error {
85 fn from(s: String) -> Error {
86 Error(Cow::Owned(s))
87 }
88}
89
90impl From<io::Error> for Error {
91 fn from(e: io::Error) -> Error {
92 Error(Cow::Owned(format!("IO error: {}", e)))
93 }
94}
95
96impl From<gimli::Error> for Error {
97 fn from(e: gimli::Error) -> Error {
98 Error(Cow::Owned(format!("DWARF error: {}", e)))
99 }
100}
101
102impl From<object::Error> for Error {
103 fn from(e: object::Error) -> Error {
104 Error(Cow::Owned(format!("object error: {}", e)))
105 }
106}
107
108pub type Result<T> = result::Result<T, Error>;
118
119mod address {
120 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
124 pub struct Address(u64);
125
126 impl Address {
127 #[inline]
129 pub fn new(address: u64) -> Address {
130 debug_assert!(Address(address) != Address::none());
131 Address(address)
132 }
133
134 #[inline]
136 pub fn none() -> Address {
137 Address(!0)
138 }
139
140 #[inline]
142 pub fn is_none(self) -> bool {
143 self == Self::none()
144 }
145
146 #[inline]
148 pub fn is_some(self) -> bool {
149 self != Self::none()
150 }
151
152 #[inline]
154 pub fn get(self) -> Option<u64> {
155 if self.is_none() { None } else { Some(self.0) }
156 }
157 }
158
159 impl Default for Address {
160 #[inline]
161 fn default() -> Self {
162 Address::none()
163 }
164 }
165}
166
167pub use crate::address::Address;
168
169mod size {
170 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
174 pub struct Size(u64);
175
176 impl Size {
177 #[inline]
179 pub fn new(size: u64) -> Size {
180 debug_assert!(Size(size) != Size::none());
181 Size(size)
182 }
183
184 #[inline]
186 pub fn none() -> Size {
187 Size(u64::MAX)
188 }
189
190 #[inline]
192 pub fn is_none(self) -> bool {
193 self == Self::none()
194 }
195
196 #[inline]
198 pub fn is_some(self) -> bool {
199 self != Self::none()
200 }
201
202 #[inline]
204 pub fn get(self) -> Option<u64> {
205 if self.is_none() { None } else { Some(self.0) }
206 }
207 }
208
209 impl Default for Size {
210 #[inline]
211 fn default() -> Self {
212 Size::none()
213 }
214 }
215
216 impl From<Option<u64>> for Size {
217 fn from(size: Option<u64>) -> Size {
218 match size {
219 Some(size) => Size::new(size),
220 None => Size::none(),
221 }
222 }
223 }
224}
225
226pub use crate::size::Size;
227
228#[derive(Debug, Default)]
229struct Id(AtomicUsize);
230
231impl Clone for Id {
232 fn clone(&self) -> Self {
233 Id(AtomicUsize::new(self.get()))
234 }
235}
236
237impl Id {
238 fn new(id: usize) -> Self {
239 Id(AtomicUsize::new(id))
240 }
241
242 fn get(&self) -> usize {
243 self.0.load(Ordering::Acquire)
244 }
245
246 fn set(&self, id: usize) {
247 self.0.store(id, Ordering::Release)
248 }
249}