| 146 | } |
| 147 | |
| 148 | fn load_section<'file, 'data>( |
| 149 | object: &'file File<'data>, |
| 150 | layout: &SectionLayout, |
| 151 | name: &str, |
| 152 | ) -> Result<Cow<'data, [u8]>, Error> { |
| 153 | let Some(section) = object.section_by_name(name) else { |
| 154 | return Ok(Cow::Borrowed(&[])); |
| 155 | }; |
| 156 | |
| 157 | let mut data = section.uncompressed_data()?; |
| 158 | |
| 159 | for (offset, reloc) in section.relocations() { |
| 160 | let data_mut = data.to_mut(); |
| 161 | |
| 162 | let (symbol_section_index, symbol_offset) = match reloc.target() { |
| 163 | RelocationTarget::Symbol(symbol) => { |
| 164 | let symbol = object |
| 165 | .symbol_by_index(symbol) |
| 166 | .map_err(|_| Error::UnexpectedElf("symbol not found"))?; |
| 167 | |
| 168 | let Some(section_index) = symbol.section().index() else { |
| 169 | Err(Error::UnexpectedElf( |
| 170 | "symbol is not associated with a section", |
| 171 | ))? |
| 172 | }; |
| 173 | |
| 174 | (section_index, symbol.address()) |
| 175 | } |
| 176 | RelocationTarget::Section(section_index) => (section_index, 0), |
| 177 | RelocationTarget::Absolute | _ => Err(Error::UnexpectedElf( |
| 178 | "absolute relocation target found in DWARF section", |
| 179 | ))?, |
| 180 | }; |
| 181 | |
| 182 | let symbol_section = object |
| 183 | .section_by_index(symbol_section_index) |
| 184 | .map_err(|_| Error::UnexpectedElf("section not found"))?; |
| 185 | |
| 186 | if symbol_section.address() != 0 { |
| 187 | Err(Error::UnexpectedElf( |
| 188 | "section address is non-zero in a relocatable file", |
| 189 | ))? |
| 190 | } |
| 191 | |
| 192 | let address = layout.encode(symbol_section_index, symbol_offset as _)?; |
| 193 | |
| 194 | let value = match reloc.kind() { |
| 195 | RelocationKind::Absolute => reloc.addend().wrapping_add(address as _), |
| 196 | RelocationKind::Relative => { |
| 197 | let ptr = layout.encode(section.index(), offset as _)?; |
| 198 | reloc |
| 199 | .addend() |
| 200 | .wrapping_add(address as _) |
| 201 | .wrapping_sub(ptr as _) |
| 202 | } |
| 203 | _ => Err(Error::UnexpectedElf("unknown relocation kind found"))?, |
| 204 | }; |
| 205 | |