Skip to content

Commit 02f1a06

Browse files
committed
Make error messages about unsupported relocations more human-readable
1 parent 4c7e40d commit 02f1a06

2 files changed

Lines changed: 84 additions & 3 deletions

File tree

crates/polkavm-linker/src/elf.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ type ElfSectionIndex = object::read::SectionIndex;
1212
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
1313
pub struct SectionIndex(usize);
1414

15+
impl SectionIndex {
16+
pub fn raw(self) -> usize {
17+
self.0
18+
}
19+
}
20+
1521
impl core::fmt::Display for SectionIndex {
1622
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
1723
write!(fmt, "section #{}", self.0)
@@ -223,6 +229,10 @@ impl<'data> Elf<'data> {
223229
&self.sections[index.0]
224230
}
225231

232+
pub fn section_by_raw_index(&self, index: usize) -> Option<&Section<'data>> {
233+
self.sections.get(index)
234+
}
235+
226236
pub fn sections<'r>(&'r self) -> impl ExactSizeIterator<Item = &'r Section<'data>> + 'r {
227237
self.sections.iter()
228238
}

crates/polkavm-linker/src/program_from_elf.rs

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ impl From<Range<u64>> for AddressRange {
330330
}
331331
}
332332

333-
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
333+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
334334
pub(crate) struct SectionTarget {
335335
pub(crate) section_index: SectionIndex,
336336
pub(crate) offset: u64,
@@ -342,7 +342,77 @@ impl core::fmt::Display for SectionTarget {
342342
}
343343
}
344344

345+
impl core::fmt::Debug for SectionTarget {
346+
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
347+
write!(fmt, "<{}+{}>", self.section_index, self.offset)
348+
}
349+
}
350+
351+
fn extract_delimited<'a>(str: &mut &'a str, prefix: &str, suffix: &str) -> Option<(&'a str, &'a str)> {
352+
let original = *str;
353+
let start_of_prefix = str.find(prefix)?;
354+
let start = start_of_prefix + prefix.len();
355+
let end = str[start..].find(suffix)? + start;
356+
*str = &str[end + suffix.len()..];
357+
Some((&original[..start_of_prefix], &original[start..end]))
358+
}
359+
360+
#[test]
361+
fn test_extract_delimited() {
362+
let mut str = "foo <section #1234+567> bar";
363+
assert_eq!(extract_delimited(&mut str, "<section #", ">").unwrap(), ("foo ", "1234+567"));
364+
assert_eq!(str, " bar");
365+
}
366+
345367
impl SectionTarget {
368+
fn make_human_readable_in_debug_string(elf: &Elf, mut str: &str) -> String {
369+
// A hack-ish way to make nested `Debug` error messages more readable by replacing
370+
// raw section indexes and offsets with a more human readable string.
371+
372+
let mut output = String::new();
373+
while let Some((prefix, chunk)) = extract_delimited(&mut str, "<section #", ">") {
374+
output.push_str(prefix);
375+
376+
let mut iter = chunk.split('+');
377+
if let Some(section_index) = iter.next().and_then(|s| s.parse::<usize>().ok()) {
378+
if let Some(offset) = iter.next().and_then(|s| s.parse::<u64>().ok()) {
379+
if let Some(section) = elf.section_by_raw_index(section_index) {
380+
use core::fmt::Write;
381+
382+
let symbol = elf.symbols().find(|symbol| {
383+
let Ok((symbol_section, symbol_offset)) = symbol.section_and_offset() else {
384+
return false;
385+
};
386+
symbol_section.index().raw() == section_index
387+
&& offset >= symbol_offset
388+
&& offset < (symbol_offset + symbol.size())
389+
});
390+
391+
let section_name = section.name();
392+
write!(&mut output, "<section #{section_index}+{offset} ('{section_name}'").unwrap();
393+
if let Some(symbol) = symbol {
394+
if let Some(symbol_name) = symbol.name() {
395+
write!(
396+
&mut output,
397+
": '{}'+{}",
398+
symbol_name,
399+
offset - symbol.section_and_offset().unwrap().1
400+
)
401+
.unwrap();
402+
}
403+
}
404+
output.push_str(")>");
405+
continue;
406+
}
407+
}
408+
}
409+
output.push_str(chunk);
410+
}
411+
412+
output.push_str(str);
413+
output
414+
}
415+
346416
fn add(self, offset: u64) -> Self {
347417
SectionTarget {
348418
section_index: self.section_index,
@@ -5573,8 +5643,9 @@ fn harvest_data_relocations(
55735643
};
55745644

55755645
return Err(ProgramFromElfError::other(format!(
5576-
"unsupported relocations for '{section_name}'[{relative_address:x}] (0x{absolute_address:08x}): {list:?}",
5577-
absolute_address = section.original_address() + relative_address
5646+
"unsupported relocations for '{section_name}'[{relative_address:x}] (0x{absolute_address:08x}): {list}",
5647+
absolute_address = section.original_address() + relative_address,
5648+
list = SectionTarget::make_human_readable_in_debug_string(elf, &format!("{list:?}")),
55785649
)));
55795650
}
55805651

0 commit comments

Comments
 (0)