gimli/read/
relocate.rs
1#[cfg(feature = "read")]
2use alloc::borrow::Cow;
3use core::fmt::Debug;
4
5use crate::common::Format;
6use crate::read::{Reader, ReaderOffset, ReaderOffsetId, Result};
7
8pub trait Relocate<T: ReaderOffset = usize> {
10 fn relocate_address(&self, offset: T, value: u64) -> Result<u64>;
12
13 fn relocate_offset(&self, offset: T, value: T) -> Result<T>;
15}
16
17#[derive(Debug, Clone)]
23pub struct RelocateReader<R: Reader<Offset = usize>, T: Relocate<R::Offset>> {
24 section: R,
25 reader: R,
26 relocate: T,
27}
28
29impl<R, T> RelocateReader<R, T>
30where
31 R: Reader<Offset = usize>,
32 T: Relocate<R::Offset>,
33{
34 pub fn new(section: R, relocate: T) -> Self {
36 let reader = section.clone();
37 Self {
38 section,
39 reader,
40 relocate,
41 }
42 }
43}
44
45impl<R, T> Reader for RelocateReader<R, T>
46where
47 R: Reader<Offset = usize>,
48 T: Relocate<R::Offset> + Debug + Clone,
49{
50 type Endian = R::Endian;
51 type Offset = R::Offset;
52
53 fn read_address(&mut self, address_size: u8) -> Result<u64> {
54 let offset = self.reader.offset_from(&self.section);
55 let value = self.reader.read_address(address_size)?;
56 self.relocate.relocate_address(offset, value)
57 }
58
59 fn read_offset(&mut self, format: Format) -> Result<R::Offset> {
60 let offset = self.reader.offset_from(&self.section);
61 let value = self.reader.read_offset(format)?;
62 self.relocate.relocate_offset(offset, value)
63 }
64
65 fn read_sized_offset(&mut self, size: u8) -> Result<R::Offset> {
66 let offset = self.reader.offset_from(&self.section);
67 let value = self.reader.read_sized_offset(size)?;
68 self.relocate.relocate_offset(offset, value)
69 }
70
71 #[inline]
72 fn split(&mut self, len: Self::Offset) -> Result<Self> {
73 let mut other = self.clone();
74 other.reader.truncate(len)?;
75 self.reader.skip(len)?;
76 Ok(other)
77 }
78
79 #[inline]
82 fn endian(&self) -> Self::Endian {
83 self.reader.endian()
84 }
85
86 #[inline]
87 fn len(&self) -> Self::Offset {
88 self.reader.len()
89 }
90
91 #[inline]
92 fn empty(&mut self) {
93 self.reader.empty()
94 }
95
96 #[inline]
97 fn truncate(&mut self, len: Self::Offset) -> Result<()> {
98 self.reader.truncate(len)
99 }
100
101 #[inline]
102 fn offset_from(&self, base: &Self) -> Self::Offset {
103 self.reader.offset_from(&base.reader)
104 }
105
106 #[inline]
107 fn offset_id(&self) -> ReaderOffsetId {
108 self.reader.offset_id()
109 }
110
111 #[inline]
112 fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<Self::Offset> {
113 self.reader.lookup_offset_id(id)
114 }
115
116 #[inline]
117 fn find(&self, byte: u8) -> Result<Self::Offset> {
118 self.reader.find(byte)
119 }
120
121 #[inline]
122 fn skip(&mut self, len: Self::Offset) -> Result<()> {
123 self.reader.skip(len)
124 }
125
126 #[cfg(not(feature = "read"))]
127 fn cannot_implement() -> super::reader::seal_if_no_alloc::Sealed {
128 super::reader::seal_if_no_alloc::Sealed
129 }
130
131 #[cfg(feature = "read")]
132 #[inline]
133 fn to_slice(&self) -> Result<Cow<'_, [u8]>> {
134 self.reader.to_slice()
135 }
136
137 #[cfg(feature = "read")]
138 #[inline]
139 fn to_string(&self) -> Result<Cow<'_, str>> {
140 self.reader.to_string()
141 }
142
143 #[cfg(feature = "read")]
144 #[inline]
145 fn to_string_lossy(&self) -> Result<Cow<'_, str>> {
146 self.reader.to_string_lossy()
147 }
148
149 #[inline]
150 fn read_slice(&mut self, buf: &mut [u8]) -> Result<()> {
151 self.reader.read_slice(buf)
152 }
153}