We are using the latest Solana monorepo [1] and our goal is to run the Solana example-helloworld [2] Using sbf-solana-solana target and sbfv2 CPU.
First, we patched programs/bpf_loader/src/syscalls/mod.rs
line 177
to set dynamic_stack_frames
to true
[3]
Second, we updated the sbf.mk
script SBF_C_FLAGS
variable and added -mcpu=sbfv2 -D SOL_SBFV2=1
. Overall the build line is like clang -Werror -O2 -fno-builtin -std=c17 -target sbf -mcpu=sbfv2 -D SOL_SBFV2=1 -fPIC -o ../../dist/program/helloworld/helloworld.o -c ./src/helloworld/helloworld.c
(-isystem
parameters skipped for readability)
As a side note, -D SOL_SBFV2=1
seems important to be added, may be related to static system calls, as we found occurrences of the SOL_SBFV2
macro in the sdk files, as for example in sdk/sbf/c/inc/sol/log.h
[4]
When we deploy the helloworld program we get the following error:
$ solana program deploy solana-example-helloworld/dist/program/helloworld.so
Error: ELF error: ELF error: Relative jump out of bounds at instruction #34
Unfortunately, the dump does not show instruction #36
[5]
However if ever we omit the -D SOL_SBFV2=1
parameter of the build command, we can deploy the program successfully, but when we run the program we get the following error:
$ npm start
...
SendTransactionError: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: Program failed to complete
at Connection.sendEncodedTransaction (GitHub/solana-example-helloworld/node_modules/@solana/web3.js/src/connection.ts:4153:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Connection.sendRawTransaction (solana-example-helloworld/node_modules/@solana/web3.js/src/connection.ts:4115:20)
at async Connection.sendTransaction (solana-example-helloworld/node_modules/@solana/web3.js/src/connection.ts:4103:12)
at async sendAndConfirmTransaction (solana-example-helloworld/node_modules/@solana/web3.js/src/util/send-and-confirm-transaction.ts:30:21) {
logs: [
'Program xxx invoke [1]',
'Program xxx consumed 5 of 200000 compute units',
'Program failed to complete: unsupported instruction at instruction 90',
'Program xxx failed: Program failed to complete'
]
}
instruction #90
is visible in the dump [6]
How to solve the ELF error: Relative jump out of bounds at instruction #34
?
Should we add additional patch to programs/bpf_loader/src/syscalls/mod.rs
? (tried without success)
Should we activate some other features for the sbf target ? [7] (tried without success)
Thanks
[1]
https://github.com/solana-labs/solana
solana-cli 1.15.0 (src:00000000
; feat:1157313049
, client:SolanaLabs)
commit 6e4ecc67587f8ff277a54b08d6ec229080354df7
[2]
https://github.com/solana-labs/example-helloworld
[3]
file programs/bpf_loader/src/syscalls/mod.rs
174 external_internal_function_hash_collision: feature_set
175 .is_active(&error_on_syscall_bpf_function_hash_collisions::id()),
176 reject_callx_r10: feature_set.is_active(&reject_callx_r10::id()),
177 dynamic_stack_frames: true,
178 enable_sdiv: false,
179 optimize_rodata: false,
180 static_syscalls: false,
181 enable_elf_vaddr: false,
182 reject_rodata_stack_overlap: false,
183 new_elf_parser: false,
184 aligned_memory_mapping: true,
185 // Warning, do not use `Config::default()` so that configuration here is explicit.
186 };
Solved thanks to How to fix 'ELF error: Dynamic stack frames detected but not enabled' while running the Solana helloworld example C program using SBF v2 processor?
[4]
file sdk/sbf/c/inc/sol/log.h
18 #ifndef SOL_SBFV2
19 void sol_log_(const char *, uint64_t);
20 #else
21 typedef void(*sol_log__pointer_type)(const char *, uint64_t);
22 static void sol_log_(const char * arg1, uint64_t arg2) {
23 sol_log__pointer_type sol_log__pointer = (sol_log__pointer_type) 544561597;
24 sol_log__pointer(arg1, arg2);
25 }
26 #endif
[5]
command V=1 make -C ./src/program-c dump_helloworld
to investigate instruction #34
when the program is built with -target sbf -mcpu=sbfv2 -D SOL_SBFV2=1
Disassembly of section .text:
0000000000000120 <helloworld>:
36: 79 12 08 00 00 00 00 00 ldxdw r2, [r1 + 8]
[6]
command V=1 make -C ./src/program-c dump_helloworld
to investigate about instruction #90
, when program is built with -target sbf -mcpu=sbfv2
0000000000000290 <LBB0_10>:
82: 79 11 18 00 00 00 00 00 ldxdw r1, [r1 + 24]
83: 61 12 00 00 00 00 00 00 ldxw r2, [r1 + 0]
84: 07 02 00 00 01 00 00 00 add64 r2, 1
85: 63 21 00 00 00 00 00 00 stxw [r1 + 0], r2
86: 18 01 00 00 05 06 00 00 00 00 00 00 00 00 00 00 lddw r1, 1541
88: b7 02 00 00 06 00 00 00 mov64 r2, 6
89: 85 10 00 00 ff ff ff ff call -1
90: b7 00 00 00 00 00 00 00 mov64 r0, 0
91: 05 00 ec ff 00 00 00 00 ja -20 <LBB0_11>
[7]
command $ llc --march=sbf --mcpu=help
alu32 - Enable ALU32 instructions.
dummy - unused feature.
dwarfris - Disable MCAsmInfo DwarfUsesRelocationsAcrossSections.
dynamic-frames - Enable dynamic frames.
reloc-abs64 - Fix 64bit data relocations.
sdiv - Enable native SBF_SDIV support.
solana - Enable Solana extensions.
static-syscalls - Marker feature used for conditional compilation.