(&self, endian: object::Endianness, bytes: &[u8])
| 118 | } |
| 119 | |
| 120 | pub fn display_literals(&self, endian: object::Endianness, bytes: &[u8]) -> Vec<LiteralInfo> { |
| 121 | let mut strs = Vec::new(); |
| 122 | if self.required_len().is_some_and(|l| bytes.len() < l) { |
| 123 | log::warn!( |
| 124 | "Failed to display a symbol value for a symbol whose size is too small for instruction referencing it." |
| 125 | ); |
| 126 | return strs; |
| 127 | } |
| 128 | let mut bytes = bytes; |
| 129 | if self.required_len().is_some_and(|l| bytes.len() > l) { |
| 130 | // If the symbol's size is larger a single instance of this data type, we take just the |
| 131 | // bytes necessary for one of them in order to display the first element of the array. |
| 132 | bytes = &bytes[0..self.required_len().unwrap()]; |
| 133 | // TODO: Attempt to interpret large symbols as arrays of a smaller type and show all |
| 134 | // elements of the array instead. https://github.com/encounter/objdiff/issues/124 |
| 135 | // However, note that the stride of an array can not always be determined just by the |
| 136 | // data type guessed by the single instruction accessing it. There can also be arrays of |
| 137 | // structs that contain multiple elements of different types, so if other elements after |
| 138 | // the first one were to be displayed in this manner, they may be inaccurate. |
| 139 | } |
| 140 | |
| 141 | match self { |
| 142 | DataType::Int8 => { |
| 143 | let i = i8::from_ne_bytes(bytes.try_into().unwrap()); |
| 144 | strs.push(LiteralInfo { literal: format!("{i:#x}"), ..Default::default() }); |
| 145 | |
| 146 | if i < 0 { |
| 147 | strs.push(LiteralInfo { |
| 148 | literal: format!("{:#x}", ReallySigned(i)), |
| 149 | ..Default::default() |
| 150 | }); |
| 151 | } |
| 152 | } |
| 153 | DataType::Int16 => { |
| 154 | let i = endian.read_i16_bytes(bytes.try_into().unwrap()); |
| 155 | strs.push(LiteralInfo { literal: format!("{i:#x}"), ..Default::default() }); |
| 156 | |
| 157 | if i < 0 { |
| 158 | strs.push(LiteralInfo { |
| 159 | literal: format!("{:#x}", ReallySigned(i)), |
| 160 | ..Default::default() |
| 161 | }); |
| 162 | } |
| 163 | } |
| 164 | DataType::Int32 => { |
| 165 | let i = endian.read_i32_bytes(bytes.try_into().unwrap()); |
| 166 | strs.push(LiteralInfo { literal: format!("{i:#x}"), ..Default::default() }); |
| 167 | |
| 168 | if i < 0 { |
| 169 | strs.push(LiteralInfo { |
| 170 | literal: format!("{:#x}", ReallySigned(i)), |
| 171 | ..Default::default() |
| 172 | }); |
| 173 | } |
| 174 | } |
| 175 | DataType::Int64 => { |
| 176 | let i = endian.read_i64_bytes(bytes.try_into().unwrap()); |
| 177 | strs.push(LiteralInfo { literal: format!("{i:#x}"), ..Default::default() }); |
no test coverage detected