Skip to content

Commit 2cb2f65

Browse files
authored
elf: add error code capturing (#370)
1 parent 3137127 commit 2cb2f65

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

src/elf_loader.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::proto;
22
use crate::proto::{ElfLoaderCtx, ElfLoaderEffects};
3+
use crate::utils::err_map::elf_err_to_num;
34
use agave_feature_set::*;
45
use agave_syscalls::create_program_runtime_environment_v1;
56
use prost::Message;
@@ -26,11 +27,17 @@ pub fn load_elf(
2627
let mut elf_effects = ElfLoaderEffects::default();
2728

2829
// load the elf
29-
let Ok(elf_exec) = Executable::load(
30+
let elf_exec = match Executable::load(
3031
elf_bytes,
3132
std::sync::Arc::new(program_runtime_environment_v1),
32-
) else {
33-
return Some(elf_effects);
33+
) {
34+
Ok(exec) => exec,
35+
Err(err) => {
36+
return Some(ElfLoaderEffects {
37+
error: elf_err_to_num(&err),
38+
..Default::default()
39+
});
40+
}
3441
};
3542

3643
let ro_section = elf_exec.get_ro_section();
@@ -46,6 +53,7 @@ pub fn load_elf(
4653
calldests.insert(fn_addr as u64);
4754
}
4855

56+
elf_effects.error = 0;
4957
elf_effects.rodata = ro_section.to_vec();
5058
elf_effects.rodata_sz = ro_section.len() as u64;
5159
elf_effects.entry_pc = elf_exec.get_entrypoint_instruction_offset() as u64;

src/utils/err_map.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use crate::proto::ErrKind;
22
use agave_syscalls::SyscallError;
33
use solana_poseidon::PoseidonSyscallError;
44
use solana_program_runtime::{invoke_context::InvokeContext, stable_log};
5-
use solana_sbpf::error::{EbpfError, StableResult};
5+
use solana_sbpf::{
6+
elf::ElfError,
7+
error::{EbpfError, StableResult},
8+
};
69

710
use solana_instruction::error::InstructionError;
811
use solana_pubkey::Pubkey;
@@ -15,6 +18,34 @@ use solana_pubkey::Pubkey;
1518
// When an err str is truncated in Firedancer, it should be explicit in this mapping,
1619
// otherwise error.to_string() is the expected value.
1720

21+
pub fn elf_err_to_num(error: &ElfError) -> i32 {
22+
match error {
23+
ElfError::FailedToParse(_) => 1,
24+
ElfError::EntrypointOutOfBounds => 2,
25+
ElfError::InvalidEntrypoint => 3,
26+
ElfError::FailedToGetSection(_) => 4,
27+
ElfError::UnresolvedSymbol(_, _, _) => 5,
28+
ElfError::SectionNotFound(_) => 6,
29+
ElfError::RelativeJumpOutOfBounds(_) => 7,
30+
ElfError::SymbolHashCollision(_) => 8,
31+
ElfError::WrongEndianess => 9,
32+
ElfError::WrongAbi => 10,
33+
ElfError::WrongMachine => 11,
34+
ElfError::WrongClass => 12,
35+
ElfError::NotOneTextSection => 13,
36+
ElfError::WritableSectionNotSupported(_) => 14,
37+
ElfError::AddressOutsideLoadableSection(_) => 15,
38+
ElfError::InvalidVirtualAddress(_) => 16,
39+
ElfError::UnknownRelocation(_) => 17,
40+
ElfError::FailedToReadRelocationInfo => 18,
41+
ElfError::WrongType => 19,
42+
ElfError::UnknownSymbol(_) => 20,
43+
ElfError::ValueOutOfBounds => 21,
44+
ElfError::UnsupportedSBPFVersion => 22,
45+
ElfError::InvalidProgramHeader => 23,
46+
}
47+
}
48+
1849
pub fn instr_err_to_num(error: &InstructionError) -> i32 {
1950
let serialized_err = bincode::serialize(error).unwrap();
2051
i32::from_le_bytes((&serialized_err[0..4]).try_into().unwrap()).saturating_add(1)

0 commit comments

Comments
 (0)