]> git.proxmox.com Git - rustc.git/blame - library/panic_unwind/src/dwarf/mod.rs
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / library / panic_unwind / src / dwarf / mod.rs
CommitLineData
c1a9b12d 1//! Utilities for parsing DWARF-encoded data streams.
9fa01778 2//! See <http://www.dwarfstd.org>,
c1a9b12d
SL
3//! DWARF-4 standard, Section 7 - "Data Representation"
4
5// This module is used only by x86_64-pc-windows-gnu for now, but we
6// are compiling it everywhere to avoid regressions.
7#![allow(unused)]
8
416331ca
XL
9#[cfg(test)]
10mod tests;
11
c1a9b12d
SL
12pub mod eh;
13
c1a9b12d
SL
14use core::mem;
15
16pub struct DwarfReader {
3157f602 17 pub ptr: *const u8,
c1a9b12d
SL
18}
19
dfeec247 20#[repr(C, packed)]
c1a9b12d
SL
21struct Unaligned<T>(T);
22
23impl DwarfReader {
3157f602 24 pub fn new(ptr: *const u8) -> DwarfReader {
a1dfa0c6 25 DwarfReader { ptr }
c1a9b12d
SL
26 }
27
0731742a 28 // DWARF streams are packed, so e.g., a u32 would not necessarily be aligned
c1a9b12d
SL
29 // on a 4-byte boundary. This may cause problems on platforms with strict
30 // alignment requirements. By wrapping data in a "packed" struct, we are
31 // telling the backend to generate "misalignment-safe" code.
3157f602 32 pub unsafe fn read<T: Copy>(&mut self) -> T {
c1a9b12d 33 let Unaligned(result) = *(self.ptr as *const Unaligned<T>);
b7449926 34 self.ptr = self.ptr.add(mem::size_of::<T>());
c1a9b12d
SL
35 result
36 }
37
38 // ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
39 // Length Data".
40 pub unsafe fn read_uleb128(&mut self) -> u64 {
3157f602
XL
41 let mut shift: usize = 0;
42 let mut result: u64 = 0;
43 let mut byte: u8;
c1a9b12d
SL
44 loop {
45 byte = self.read::<u8>();
46 result |= ((byte & 0x7F) as u64) << shift;
47 shift += 7;
48 if byte & 0x80 == 0 {
49 break;
50 }
51 }
52 result
53 }
54
55 pub unsafe fn read_sleb128(&mut self) -> i64 {
1b1a35ee 56 let mut shift: u32 = 0;
3157f602
XL
57 let mut result: u64 = 0;
58 let mut byte: u8;
c1a9b12d
SL
59 loop {
60 byte = self.read::<u8>();
61 result |= ((byte & 0x7F) as u64) << shift;
62 shift += 7;
63 if byte & 0x80 == 0 {
64 break;
65 }
66 }
67 // sign-extend
1b1a35ee 68 if shift < u64::BITS && (byte & 0x40) != 0 {
c1a9b12d
SL
69 result |= (!0 as u64) << shift;
70 }
71 result as i64
72 }
73}