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