| 1 | /// Whether the format of a compilation unit is 32- or 64-bit. |
| 2 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 3 | pub enum Format { |
| 4 | /// 64-bit DWARF |
| 5 | Dwarf64 = 8, |
| 6 | /// 32-bit DWARF |
| 7 | Dwarf32 = 4, |
| 8 | } |
| 9 | |
| 10 | impl Format { |
| 11 | /// Return the serialized size of an initial length field for the format. |
| 12 | #[inline ] |
| 13 | pub fn initial_length_size(self) -> u8 { |
| 14 | match self { |
| 15 | Format::Dwarf32 => 4, |
| 16 | Format::Dwarf64 => 12, |
| 17 | } |
| 18 | } |
| 19 | |
| 20 | /// Return the natural word size for the format |
| 21 | #[inline ] |
| 22 | pub fn word_size(self) -> u8 { |
| 23 | match self { |
| 24 | Format::Dwarf32 => 4, |
| 25 | Format::Dwarf64 => 8, |
| 26 | } |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | /// Which vendor extensions to support. |
| 31 | #[derive (Clone, Copy, Debug, PartialEq, Eq)] |
| 32 | #[non_exhaustive ] |
| 33 | pub enum Vendor { |
| 34 | /// A default set of extensions, including some common GNU extensions. |
| 35 | Default, |
| 36 | /// AAarch64 extensions. |
| 37 | AArch64, |
| 38 | } |
| 39 | |
| 40 | /// Encoding parameters that are commonly used for multiple DWARF sections. |
| 41 | /// |
| 42 | /// This is intended to be small enough to pass by value. |
| 43 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 44 | // `address_size` and `format` are used more often than `version`, so keep |
| 45 | // them first. |
| 46 | #[repr (C)] |
| 47 | pub struct Encoding { |
| 48 | /// The size of an address. |
| 49 | pub address_size: u8, |
| 50 | |
| 51 | /// Whether the DWARF format is 32- or 64-bit. |
| 52 | pub format: Format, |
| 53 | |
| 54 | /// The DWARF version of the header. |
| 55 | pub version: u16, |
| 56 | } |
| 57 | |
| 58 | /// Encoding parameters for a line number program. |
| 59 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 60 | pub struct LineEncoding { |
| 61 | /// The size in bytes of the smallest target machine instruction. |
| 62 | pub minimum_instruction_length: u8, |
| 63 | |
| 64 | /// The maximum number of individual operations that may be encoded in an |
| 65 | /// instruction. |
| 66 | pub maximum_operations_per_instruction: u8, |
| 67 | |
| 68 | /// The initial value of the `is_stmt` register. |
| 69 | pub default_is_stmt: bool, |
| 70 | |
| 71 | /// The minimum value which a special opcode can add to the line register. |
| 72 | pub line_base: i8, |
| 73 | |
| 74 | /// The range of values which a special opcode can add to the line register. |
| 75 | pub line_range: u8, |
| 76 | } |
| 77 | |
| 78 | impl Default for LineEncoding { |
| 79 | fn default() -> Self { |
| 80 | // Values from LLVM. |
| 81 | LineEncoding { |
| 82 | minimum_instruction_length: 1, |
| 83 | maximum_operations_per_instruction: 1, |
| 84 | default_is_stmt: true, |
| 85 | line_base: -5, |
| 86 | line_range: 14, |
| 87 | } |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | /// A DWARF register number. |
| 92 | /// |
| 93 | /// The meaning of this value is ABI dependent. This is generally encoded as |
| 94 | /// a ULEB128, but supported architectures need 16 bits at most. |
| 95 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] |
| 96 | pub struct Register(pub u16); |
| 97 | |
| 98 | /// An offset into the `.debug_abbrev` section. |
| 99 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 100 | pub struct DebugAbbrevOffset<T = usize>(pub T); |
| 101 | |
| 102 | /// An offset to a set of entries in the `.debug_addr` section. |
| 103 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 104 | pub struct DebugAddrBase<T = usize>(pub T); |
| 105 | |
| 106 | /// An index into a set of addresses in the `.debug_addr` section. |
| 107 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 108 | pub struct DebugAddrIndex<T = usize>(pub T); |
| 109 | |
| 110 | /// An offset into the `.debug_aranges` section. |
| 111 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 112 | pub struct DebugArangesOffset<T = usize>(pub T); |
| 113 | |
| 114 | /// An offset into the `.debug_info` section. |
| 115 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] |
| 116 | pub struct DebugInfoOffset<T = usize>(pub T); |
| 117 | |
| 118 | /// An offset into the `.debug_line` section. |
| 119 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 120 | pub struct DebugLineOffset<T = usize>(pub T); |
| 121 | |
| 122 | /// An offset into the `.debug_line_str` section. |
| 123 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 124 | pub struct DebugLineStrOffset<T = usize>(pub T); |
| 125 | |
| 126 | /// An offset into either the `.debug_loc` section or the `.debug_loclists` section, |
| 127 | /// depending on the version of the unit the offset was contained in. |
| 128 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 129 | pub struct LocationListsOffset<T = usize>(pub T); |
| 130 | |
| 131 | /// An offset to a set of location list offsets in the `.debug_loclists` section. |
| 132 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 133 | pub struct DebugLocListsBase<T = usize>(pub T); |
| 134 | |
| 135 | /// An index into a set of location list offsets in the `.debug_loclists` section. |
| 136 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 137 | pub struct DebugLocListsIndex<T = usize>(pub T); |
| 138 | |
| 139 | /// An offset into the `.debug_macinfo` section. |
| 140 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 141 | pub struct DebugMacinfoOffset<T = usize>(pub T); |
| 142 | |
| 143 | /// An offset into the `.debug_macro` section. |
| 144 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 145 | pub struct DebugMacroOffset<T = usize>(pub T); |
| 146 | |
| 147 | /// An offset into either the `.debug_ranges` section or the `.debug_rnglists` section, |
| 148 | /// depending on the version of the unit the offset was contained in. |
| 149 | /// |
| 150 | /// If this is from a DWARF 4 DWO file, then it must additionally be offset by the |
| 151 | /// value of `DW_AT_GNU_ranges_base`. You can use `Dwarf::ranges_offset_from_raw` to do this. |
| 152 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 153 | pub struct RawRangeListsOffset<T = usize>(pub T); |
| 154 | |
| 155 | /// An offset into either the `.debug_ranges` section or the `.debug_rnglists` section, |
| 156 | /// depending on the version of the unit the offset was contained in. |
| 157 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 158 | pub struct RangeListsOffset<T = usize>(pub T); |
| 159 | |
| 160 | /// An offset to a set of range list offsets in the `.debug_rnglists` section. |
| 161 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 162 | pub struct DebugRngListsBase<T = usize>(pub T); |
| 163 | |
| 164 | /// An index into a set of range list offsets in the `.debug_rnglists` section. |
| 165 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 166 | pub struct DebugRngListsIndex<T = usize>(pub T); |
| 167 | |
| 168 | /// An offset into the `.debug_str` section. |
| 169 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 170 | pub struct DebugStrOffset<T = usize>(pub T); |
| 171 | |
| 172 | /// An offset to a set of entries in the `.debug_str_offsets` section. |
| 173 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 174 | pub struct DebugStrOffsetsBase<T = usize>(pub T); |
| 175 | |
| 176 | /// An index into a set of entries in the `.debug_str_offsets` section. |
| 177 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 178 | pub struct DebugStrOffsetsIndex<T = usize>(pub T); |
| 179 | |
| 180 | /// An offset into the `.debug_types` section. |
| 181 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] |
| 182 | pub struct DebugTypesOffset<T = usize>(pub T); |
| 183 | |
| 184 | /// A type signature as used in the `.debug_types` section. |
| 185 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 186 | pub struct DebugTypeSignature(pub u64); |
| 187 | |
| 188 | /// An offset into the `.debug_frame` section. |
| 189 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 190 | pub struct DebugFrameOffset<T = usize>(pub T); |
| 191 | |
| 192 | impl<T> From<T> for DebugFrameOffset<T> { |
| 193 | #[inline ] |
| 194 | fn from(o: T) -> Self { |
| 195 | DebugFrameOffset(o) |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | /// An offset into the `.eh_frame` section. |
| 200 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 201 | pub struct EhFrameOffset<T = usize>(pub T); |
| 202 | |
| 203 | impl<T> From<T> for EhFrameOffset<T> { |
| 204 | #[inline ] |
| 205 | fn from(o: T) -> Self { |
| 206 | EhFrameOffset(o) |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | /// An offset into the `.debug_info` or `.debug_types` sections. |
| 211 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] |
| 212 | pub enum UnitSectionOffset<T = usize> { |
| 213 | /// An offset into the `.debug_info` section. |
| 214 | DebugInfoOffset(DebugInfoOffset<T>), |
| 215 | /// An offset into the `.debug_types` section. |
| 216 | DebugTypesOffset(DebugTypesOffset<T>), |
| 217 | } |
| 218 | |
| 219 | impl<T> From<DebugInfoOffset<T>> for UnitSectionOffset<T> { |
| 220 | fn from(offset: DebugInfoOffset<T>) -> Self { |
| 221 | UnitSectionOffset::DebugInfoOffset(offset) |
| 222 | } |
| 223 | } |
| 224 | |
| 225 | impl<T> From<DebugTypesOffset<T>> for UnitSectionOffset<T> { |
| 226 | fn from(offset: DebugTypesOffset<T>) -> Self { |
| 227 | UnitSectionOffset::DebugTypesOffset(offset) |
| 228 | } |
| 229 | } |
| 230 | |
| 231 | impl<T> UnitSectionOffset<T> |
| 232 | where |
| 233 | T: Clone, |
| 234 | { |
| 235 | /// Returns the `DebugInfoOffset` inside, or `None` otherwise. |
| 236 | pub fn as_debug_info_offset(&self) -> Option<DebugInfoOffset<T>> { |
| 237 | match self { |
| 238 | UnitSectionOffset::DebugInfoOffset(offset: &DebugInfoOffset) => Some(offset.clone()), |
| 239 | UnitSectionOffset::DebugTypesOffset(_) => None, |
| 240 | } |
| 241 | } |
| 242 | /// Returns the `DebugTypesOffset` inside, or `None` otherwise. |
| 243 | pub fn as_debug_types_offset(&self) -> Option<DebugTypesOffset<T>> { |
| 244 | match self { |
| 245 | UnitSectionOffset::DebugInfoOffset(_) => None, |
| 246 | UnitSectionOffset::DebugTypesOffset(offset: &DebugTypesOffset) => Some(offset.clone()), |
| 247 | } |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | /// An identifier for a DWARF section. |
| 252 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] |
| 253 | pub enum SectionId { |
| 254 | /// The `.debug_abbrev` section. |
| 255 | DebugAbbrev, |
| 256 | /// The `.debug_addr` section. |
| 257 | DebugAddr, |
| 258 | /// The `.debug_aranges` section. |
| 259 | DebugAranges, |
| 260 | /// The `.debug_cu_index` section. |
| 261 | DebugCuIndex, |
| 262 | /// The `.debug_frame` section. |
| 263 | DebugFrame, |
| 264 | /// The `.eh_frame` section. |
| 265 | EhFrame, |
| 266 | /// The `.eh_frame_hdr` section. |
| 267 | EhFrameHdr, |
| 268 | /// The `.debug_info` section. |
| 269 | DebugInfo, |
| 270 | /// The `.debug_line` section. |
| 271 | DebugLine, |
| 272 | /// The `.debug_line_str` section. |
| 273 | DebugLineStr, |
| 274 | /// The `.debug_loc` section. |
| 275 | DebugLoc, |
| 276 | /// The `.debug_loclists` section. |
| 277 | DebugLocLists, |
| 278 | /// The `.debug_macinfo` section. |
| 279 | DebugMacinfo, |
| 280 | /// The `.debug_macro` section. |
| 281 | DebugMacro, |
| 282 | /// The `.debug_pubnames` section. |
| 283 | DebugPubNames, |
| 284 | /// The `.debug_pubtypes` section. |
| 285 | DebugPubTypes, |
| 286 | /// The `.debug_ranges` section. |
| 287 | DebugRanges, |
| 288 | /// The `.debug_rnglists` section. |
| 289 | DebugRngLists, |
| 290 | /// The `.debug_str` section. |
| 291 | DebugStr, |
| 292 | /// The `.debug_str_offsets` section. |
| 293 | DebugStrOffsets, |
| 294 | /// The `.debug_tu_index` section. |
| 295 | DebugTuIndex, |
| 296 | /// The `.debug_types` section. |
| 297 | DebugTypes, |
| 298 | } |
| 299 | |
| 300 | impl SectionId { |
| 301 | /// Returns the ELF section name for this kind. |
| 302 | pub fn name(self) -> &'static str { |
| 303 | match self { |
| 304 | SectionId::DebugAbbrev => ".debug_abbrev" , |
| 305 | SectionId::DebugAddr => ".debug_addr" , |
| 306 | SectionId::DebugAranges => ".debug_aranges" , |
| 307 | SectionId::DebugCuIndex => ".debug_cu_index" , |
| 308 | SectionId::DebugFrame => ".debug_frame" , |
| 309 | SectionId::EhFrame => ".eh_frame" , |
| 310 | SectionId::EhFrameHdr => ".eh_frame_hdr" , |
| 311 | SectionId::DebugInfo => ".debug_info" , |
| 312 | SectionId::DebugLine => ".debug_line" , |
| 313 | SectionId::DebugLineStr => ".debug_line_str" , |
| 314 | SectionId::DebugLoc => ".debug_loc" , |
| 315 | SectionId::DebugLocLists => ".debug_loclists" , |
| 316 | SectionId::DebugMacinfo => ".debug_macinfo" , |
| 317 | SectionId::DebugMacro => ".debug_macro" , |
| 318 | SectionId::DebugPubNames => ".debug_pubnames" , |
| 319 | SectionId::DebugPubTypes => ".debug_pubtypes" , |
| 320 | SectionId::DebugRanges => ".debug_ranges" , |
| 321 | SectionId::DebugRngLists => ".debug_rnglists" , |
| 322 | SectionId::DebugStr => ".debug_str" , |
| 323 | SectionId::DebugStrOffsets => ".debug_str_offsets" , |
| 324 | SectionId::DebugTuIndex => ".debug_tu_index" , |
| 325 | SectionId::DebugTypes => ".debug_types" , |
| 326 | } |
| 327 | } |
| 328 | |
| 329 | /// Returns the ELF section name for this kind, when found in a .dwo or .dwp file. |
| 330 | pub fn dwo_name(self) -> Option<&'static str> { |
| 331 | Some(match self { |
| 332 | SectionId::DebugAbbrev => ".debug_abbrev.dwo" , |
| 333 | SectionId::DebugCuIndex => ".debug_cu_index" , |
| 334 | SectionId::DebugInfo => ".debug_info.dwo" , |
| 335 | SectionId::DebugLine => ".debug_line.dwo" , |
| 336 | // The debug_loc section can be present in the dwo when using the |
| 337 | // GNU split-dwarf extension to DWARF4. |
| 338 | SectionId::DebugLoc => ".debug_loc.dwo" , |
| 339 | SectionId::DebugLocLists => ".debug_loclists.dwo" , |
| 340 | SectionId::DebugMacinfo => ".debug_macinfo.dwo" , |
| 341 | SectionId::DebugMacro => ".debug_macro.dwo" , |
| 342 | SectionId::DebugRngLists => ".debug_rnglists.dwo" , |
| 343 | SectionId::DebugStr => ".debug_str.dwo" , |
| 344 | SectionId::DebugStrOffsets => ".debug_str_offsets.dwo" , |
| 345 | SectionId::DebugTuIndex => ".debug_tu_index" , |
| 346 | SectionId::DebugTypes => ".debug_types.dwo" , |
| 347 | _ => return None, |
| 348 | }) |
| 349 | } |
| 350 | |
| 351 | /// Returns the XCOFF section name for this kind. |
| 352 | pub fn xcoff_name(self) -> Option<&'static str> { |
| 353 | Some(match self { |
| 354 | SectionId::DebugAbbrev => ".dwabrev" , |
| 355 | SectionId::DebugAranges => ".dwarnge" , |
| 356 | SectionId::DebugFrame => ".dwframe" , |
| 357 | SectionId::DebugInfo => ".dwinfo" , |
| 358 | SectionId::DebugLine => ".dwline" , |
| 359 | SectionId::DebugLoc => ".dwloc" , |
| 360 | SectionId::DebugMacinfo => ".dwmac" , |
| 361 | SectionId::DebugPubNames => ".dwpbnms" , |
| 362 | SectionId::DebugPubTypes => ".dwpbtyp" , |
| 363 | SectionId::DebugRanges => ".dwrnges" , |
| 364 | SectionId::DebugStr => ".dwstr" , |
| 365 | _ => return None, |
| 366 | }) |
| 367 | } |
| 368 | |
| 369 | /// Returns true if this is a mergeable string section. |
| 370 | /// |
| 371 | /// This is useful for determining the correct section flags. |
| 372 | pub fn is_string(self) -> bool { |
| 373 | matches!(self, SectionId::DebugStr | SectionId::DebugLineStr) |
| 374 | } |
| 375 | } |
| 376 | |
| 377 | /// An optionally-provided implementation-defined compilation unit ID to enable |
| 378 | /// split DWARF and linking a split compilation unit back together. |
| 379 | #[derive (Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| 380 | pub struct DwoId(pub u64); |
| 381 | |
| 382 | /// The "type" of file with DWARF debugging information. This determines, among other things, |
| 383 | /// which files DWARF sections should be loaded from. |
| 384 | #[derive (Debug, Clone, Copy, PartialEq, Eq)] |
| 385 | pub enum DwarfFileType { |
| 386 | /// A normal executable or object file. |
| 387 | Main, |
| 388 | /// A .dwo split DWARF file. |
| 389 | Dwo, |
| 390 | // TODO: Supplementary files, .dwps? |
| 391 | } |
| 392 | |
| 393 | impl Default for DwarfFileType { |
| 394 | fn default() -> Self { |
| 395 | DwarfFileType::Main |
| 396 | } |
| 397 | } |
| 398 | |