Generate syscall headers

This commit is contained in:
Dmitri Makarov 2022-04-25 15:16:31 -07:00 committed by Dmitri Makarov
parent 0cc97689f9
commit 66366615bb
26 changed files with 970 additions and 46 deletions

8
Cargo.lock generated
View File

@ -1566,6 +1566,14 @@ dependencies = [
"tempfile",
]
[[package]]
name = "gen-headers"
version = "1.11.0"
dependencies = [
"log",
"regex",
]
[[package]]
name = "gen-syscall-list"
version = "1.11.0"

View File

@ -67,6 +67,7 @@ members = [
"sdk",
"sdk/cargo-build-bpf",
"sdk/cargo-test-bpf",
"sdk/gen-headers",
"send-transaction-service",
"stake-accounts",
"storage-bigtable",

View File

@ -148,6 +148,8 @@ fi
if [[ -z "$validatorOnly" ]]; then
# shellcheck disable=SC2086 # Don't want to double quote $rust_version
"$cargo" $maybeRustVersion build --manifest-path programs/bpf_loader/gen-syscall-list/Cargo.toml
# shellcheck disable=SC2086 # Don't want to double quote $rust_version
"$cargo" $maybeRustVersion run --bin gen-headers
mkdir -p "$installDir"/bin/sdk/bpf
cp -a sdk/bpf/* "$installDir"/bin/sdk/bpf
fi

View File

@ -41,6 +41,12 @@ C_FLAGS := \
$(addprefix -I,$(STD_INC_DIRS)) \
$(addprefix -I,$(INC_DIRS)) \
ifeq ($(SOL_SBFV2),1)
C_FLAGS := \
$(C_FLAGS) \
-DSOL_SBFV2=1
endif
CXX_FLAGS := \
$(C_FLAGS) \
-std=c++17 \
@ -70,6 +76,12 @@ BPF_LLD_FLAGS := \
-L $(STD_LIB_DIRS) \
-lc \
ifeq ($(SOL_SBFV2),1)
BPF_LLD_FLAGS := \
$(BPF_LLD_FLAGS) \
--pack-dyn-relocs=relr
endif
OBJ_DUMP_FLAGS := \
--source \
--disassemble \

View File

@ -16,7 +16,15 @@ extern "C" {
* Prints the line number where the panic occurred and then causes
* the BPF VM to immediately halt execution. No accounts' data are updated
*/
#ifndef SOL_SBFV2
void sol_panic_(const char *, uint64_t, uint64_t, uint64_t);
#else
typedef void(*sol_panic__pointer_type)(const char *, uint64_t, uint64_t, uint64_t);
static void sol_panic_(const char * arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4) {
sol_panic__pointer_type sol_panic__pointer = (sol_panic__pointer_type) 1751159739;
sol_panic__pointer(arg1, arg2, arg3, arg4);
}
#endif
#define sol_panic() sol_panic_(__FILE__, sizeof(__FILE__), __LINE__, 0)
/**

View File

@ -21,11 +21,15 @@ extern "C" {
* @param bytes_len Number of byte arrays
* @param result 32 byte array to hold the result
*/
uint64_t sol_blake3(
const SolBytes *bytes,
int bytes_len,
const uint8_t *result
);
#ifndef SOL_SBFV2
uint64_t sol_blake3(const SolBytes *, int, const uint8_t *);
#else
typedef uint64_t(*sol_blake3_pointer_type)(const SolBytes *, int, const uint8_t *);
static uint64_t sol_blake3(const SolBytes * arg1, int arg2, const uint8_t * arg3) {
sol_blake3_pointer_type sol_blake3_pointer = (sol_blake3_pointer_type) 390877474;
return sol_blake3_pointer(arg1, arg2, arg3);
}
#endif
#ifdef __cplusplus
}

View File

@ -34,13 +34,33 @@ typedef struct {
/**
* Internal cross-program invocation function
*/
#ifndef SOL_SBFV2
uint64_t sol_invoke_signed_c(
const SolInstruction *instruction,
const SolAccountInfo *account_infos,
int account_infos_len,
const SolSignerSeeds *signers_seeds,
int signers_seeds_len
const SolInstruction *,
const SolAccountInfo *,
int,
const SolSignerSeeds *,
int
);
#else
typedef uint64_t(*sol_invoke_signed_c_pointer_type)(
const SolInstruction *,
const SolAccountInfo *,
int,
const SolSignerSeeds *,
int
);
static uint64_t sol_invoke_signed_c(
const SolInstruction * arg1,
const SolAccountInfo * arg2,
int arg3,
const SolSignerSeeds * arg4,
int
arg5) {
sol_invoke_signed_c_pointer_type sol_invoke_signed_c_pointer = (sol_invoke_signed_c_pointer_type) 2720767109;
return sol_invoke_signed_c_pointer(arg1, arg2, arg3, arg4, arg5);
}
#endif
/**
* Invoke another program and sign for some of the keys

View File

@ -0,0 +1,47 @@
#pragma once
/**
* @brief Solana assert and panic utilities
*/
#include <sol/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Panics
*
* Prints the line number where the panic occurred and then causes
* the BPF VM to immediately halt execution. No accounts' data are updated
*/
@SYSCALL void sol_panic_(const char *, uint64_t, uint64_t, uint64_t);
#define sol_panic() sol_panic_(__FILE__, sizeof(__FILE__), __LINE__, 0)
/**
* Asserts
*/
#define sol_assert(expr) \
if (!(expr)) { \
sol_panic(); \
}
#ifdef SOL_TEST
/**
* Stub functions when building tests
*/
#include <stdio.h>
#include <stdlib.h>
void sol_panic_(const char *file, uint64_t len, uint64_t line, uint64_t column) {
printf("Panic in %s at %d:%d\n", file, line, column);
abort();
}
#endif
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -0,0 +1,30 @@
#pragma once
/**
* @brief Solana Blake3 system call
*/
#include <sol/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Length of a Blake3 hash result
*/
#define BLAKE3_RESULT_LENGTH 32
/**
* Blake3
*
* @param bytes Array of byte arrays
* @param bytes_len Number of byte arrays
* @param result 32 byte array to hold the result
*/
@SYSCALL uint64_t sol_blake3(const SolBytes *, int, const uint8_t *);
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -0,0 +1,95 @@
#pragma once
/**
* @brief Solana Cross-Program Invocation
*/
#include <sol/types.h>
#include <sol/pubkey.h>
#include <sol/entrypoint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Account Meta
*/
typedef struct {
SolPubkey *pubkey; /** An account's public key */
bool is_writable; /** True if the `pubkey` can be loaded as a read-write account */
bool is_signer; /** True if an Instruction requires a Transaction signature matching `pubkey` */
} SolAccountMeta;
/**
* Instruction
*/
typedef struct {
SolPubkey *program_id; /** Pubkey of the instruction processor that executes this instruction */
SolAccountMeta *accounts; /** Metadata for what accounts should be passed to the instruction processor */
uint64_t account_len; /** Number of SolAccountMetas */
uint8_t *data; /** Opaque data passed to the instruction processor */
uint64_t data_len; /** Length of the data in bytes */
} SolInstruction;
/**
* Internal cross-program invocation function
*/
@SYSCALL uint64_t sol_invoke_signed_c(
const SolInstruction *,
const SolAccountInfo *,
int,
const SolSignerSeeds *,
int
);
/**
* Invoke another program and sign for some of the keys
*
* @param instruction Instruction to process
* @param account_infos Accounts used by instruction
* @param account_infos_len Length of account_infos array
* @param seeds Seed bytes used to sign program accounts
* @param seeds_len Length of the seeds array
*/
static uint64_t sol_invoke_signed(
const SolInstruction *instruction,
const SolAccountInfo *account_infos,
int account_infos_len,
const SolSignerSeeds *signers_seeds,
int signers_seeds_len
) {
return sol_invoke_signed_c(
instruction,
account_infos,
account_infos_len,
signers_seeds,
signers_seeds_len
);
}
/**
* Invoke another program
*
* @param instruction Instruction to process
* @param account_infos Accounts used by instruction
* @param account_infos_len Length of account_infos array
*/
static uint64_t sol_invoke(
const SolInstruction *instruction,
const SolAccountInfo *account_infos,
int account_infos_len
) {
const SolSignerSeeds signers_seeds[] = {{}};
return sol_invoke_signed(
instruction,
account_infos,
account_infos_len,
signers_seeds,
0
);
}
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -0,0 +1,30 @@
#pragma once
/**
* @brief Solana keccak system call
**/
#include <sol/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Length of a Keccak hash result
*/
#define KECCAK_RESULT_LENGTH 32
/**
* Keccak
*
* @param bytes Array of byte arrays
* @param bytes_len Number of byte arrays
* @param result 32 byte array to hold the result
*/
@SYSCALL uint64_t sol_keccak256(const SolBytes *, int, uint8_t *);
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -0,0 +1,103 @@
#pragma once
/**
* @brief Solana logging utilities
*/
#include <sol/types.h>
#include <sol/string.h>
#include <sol/entrypoint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Prints a string to stdout
*/
@SYSCALL void sol_log_(const char *, uint64_t);
#define sol_log(message) sol_log_(message, sol_strlen(message))
/**
* Prints a 64 bit values represented in hexadecimal to stdout
*/
@SYSCALL void sol_log_64_(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
#define sol_log_64 sol_log_64_
/**
* Prints the current compute unit consumption to stdout
*/
@SYSCALL void sol_log_compute_units_();
#define sol_log_compute_units() sol_log_compute_units_()
/**
* Prints the hexadecimal representation of an array
*
* @param array The array to print
*/
static void sol_log_array(const uint8_t *array, int len) {
for (int j = 0; j < len; j++) {
sol_log_64(0, 0, 0, j, array[j]);
}
}
/**
* Print the base64 representation of some arrays.
*/
@SYSCALL void sol_log_data(SolBytes *, uint64_t);
/**
* Prints the program's input parameters
*
* @param params Pointer to a SolParameters structure
*/
static void sol_log_params(const SolParameters *params) {
sol_log("- Program identifier:");
sol_log_pubkey(params->program_id);
sol_log("- Number of KeyedAccounts");
sol_log_64(0, 0, 0, 0, params->ka_num);
for (int i = 0; i < params->ka_num; i++) {
sol_log(" - Is signer");
sol_log_64(0, 0, 0, 0, params->ka[i].is_signer);
sol_log(" - Is writable");
sol_log_64(0, 0, 0, 0, params->ka[i].is_writable);
sol_log(" - Key");
sol_log_pubkey(params->ka[i].key);
sol_log(" - Lamports");
sol_log_64(0, 0, 0, 0, *params->ka[i].lamports);
sol_log(" - data");
sol_log_array(params->ka[i].data, params->ka[i].data_len);
sol_log(" - Owner");
sol_log_pubkey(params->ka[i].owner);
sol_log(" - Executable");
sol_log_64(0, 0, 0, 0, params->ka[i].executable);
sol_log(" - Rent Epoch");
sol_log_64(0, 0, 0, 0, params->ka[i].rent_epoch);
}
sol_log("- Instruction data\0");
sol_log_array(params->data, params->data_len);
}
#ifdef SOL_TEST
/**
* Stub functions when building tests
*/
#include <stdio.h>
void sol_log_(const char *s, uint64_t len) {
printf("Program log: %s\n", s);
}
void sol_log_64(uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5) {
printf("Program log: %llu, %llu, %llu, %llu, %llu\n", arg1, arg2, arg3, arg4, arg5);
}
void sol_log_compute_units_() {
printf("Program consumption: __ units remaining\n");
}
#endif
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -0,0 +1,107 @@
#pragma once
/**
* @brief Solana Public key
*/
#include <sol/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Size of Public key in bytes
*/
#define SIZE_PUBKEY 32
/**
* Public key
*/
typedef struct {
uint8_t x[SIZE_PUBKEY];
} SolPubkey;
/**
* Prints the hexadecimal representation of a public key
*
* @param key The public key to print
*/
@SYSCALL void sol_log_pubkey(const SolPubkey *);
/**
* Compares two public keys
*
* @param one First public key
* @param two Second public key
* @return true if the same
*/
static bool SolPubkey_same(const SolPubkey *one, const SolPubkey *two) {
for (int i = 0; i < sizeof(*one); i++) {
if (one->x[i] != two->x[i]) {
return false;
}
}
return true;
}
/**
* Seed used to create a program address or passed to sol_invoke_signed
*/
typedef struct {
const uint8_t *addr; /** Seed bytes */
uint64_t len; /** Length of the seed bytes */
} SolSignerSeed;
/**
* Seeds used by a signer to create a program address or passed to
* sol_invoke_signed
*/
typedef struct {
const SolSignerSeed *addr; /** An array of a signer's seeds */
uint64_t len; /** Number of seeds */
} SolSignerSeeds;
/**
* Create a program address
*
* @param seeds Seed bytes used to sign program accounts
* @param seeds_len Length of the seeds array
* @param program_id Program id of the signer
* @param program_address Program address created, filled on return
*/
@SYSCALL uint64_t sol_create_program_address(const SolSignerSeed *, int, const SolPubkey *, SolPubkey *);
/**
* Try to find a program address and return corresponding bump seed
*
* @param seeds Seed bytes used to sign program accounts
* @param seeds_len Length of the seeds array
* @param program_id Program id of the signer
* @param program_address Program address created, filled on return
* @param bump_seed Bump seed required to create a valid program address
*/
@SYSCALL uint64_t sol_try_find_program_address(const SolSignerSeed *, int, const SolPubkey *, SolPubkey *, uint8_t *);
#ifdef SOL_TEST
/**
* Stub functions when building tests
*/
#include <stdio.h>
void sol_log_pubkey(
const SolPubkey *pubkey
) {
printf("Program log: ");
for (int i = 0; i < SIZE_PUBKEY; i++) {
printf("%02 ", pubkey->x[i]);
}
printf("\n");
}
#endif
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -0,0 +1,41 @@
#pragma once
/**
* @brief Solana return data system calls
**/
#include <sol/types.h>
#include <sol/pubkey.h>
#ifdef __cplusplus
extern "C"
{
#endif
/**
* Maximum size of return data
*/
#define MAX_RETURN_DATA 1024
/**
* Set the return data
*
* @param bytes byte array to set
* @param bytes_len length of byte array. This may not exceed MAX_RETURN_DATA.
*/
@SYSCALL void sol_set_return_data(const uint8_t *, uint64_t);
/**
* Get the return data
*
* @param bytes byte buffer
* @param bytes_len maximum length of buffer
* @param program_id the program_id which set the return data. Only set if there was some return data (the function returns non-zero).
* @param result length of return data (may exceed bytes_len if the return data is longer)
*/
@SYSCALL uint64_t sol_get_return_data(const uint8_t *, uint64_t, SolPubkey *);
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -0,0 +1,41 @@
#pragma once
/**
* @brief Solana secp256k1 system call
*/
#include <sol/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Length of a secp256k1 recover input hash */
#define SECP256K1_RECOVER_HASH_LENGTH 32
/** Length of a secp256k1 input signature */
#define SECP256K1_RECOVER_SIGNATURE_LENGTH 64
/** Length of a secp256k1 recover result */
#define SECP256K1_RECOVER_RESULT_LENGTH 64
/** The hash provided to a sol_secp256k1_recover is invalid */
#define SECP256K1_RECOVER_ERROR_INVALID_HASH 1
/** The recovery_id provided to a sol_secp256k1_recover is invalid */
#define SECP256K1_RECOVER_ERROR_INVALID_RECOVERY_ID 2
/** The signature provided to a sol_secp256k1_recover is invalid */
#define SECP256K1_RECOVER_ERROR_INVALID_SIGNATURE 3
/**
* Recover public key from a signed message.
*
* @param hash Hashed message
* @param recovery_id Tag used for public key recovery from signatures. Can be 0 or 1
* @param signature An ECDSA signature
* @param result 64 byte array to hold the result. A recovered public key
* @return 0 if executed successfully
*/
@SYSCALL uint64_t sol_secp256k1_recover(const uint8_t *, uint64_t, const uint8_t *, uint8_t *);
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -0,0 +1,30 @@
#pragma once
/**
* @brief Solana sha system call
*/
#include <sol/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Length of a sha256 hash result
*/
#define SHA256_RESULT_LENGTH 32
/**
* Sha256
*
* @param bytes Array of byte arrays
* @param bytes_len Number of byte arrays
* @param result 32 byte array to hold the result
*/
@SYSCALL uint64_t sol_sha256(const SolBytes *, int, uint8_t *);
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -0,0 +1,81 @@
#pragma once
/**
* @brief Solana string and memory system calls and utilities
*/
#include <sol/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Copies memory
*/
static void sol_memcpy(void *dst, const void *src, int len) {
for (int i = 0; i < len; i++) {
*((uint8_t *)dst + i) = *((const uint8_t *)src + i);
}
}
/**
* Compares memory
*/
static int sol_memcmp(const void *s1, const void *s2, int n) {
for (int i = 0; i < n; i++) {
uint8_t diff = *((uint8_t *)s1 + i) - *((const uint8_t *)s2 + i);
if (diff) {
return diff;
}
}
return 0;
}
/**
* Fill a byte string with a byte value
*/
static void *sol_memset(void *b, int c, size_t len) {
uint8_t *a = (uint8_t *) b;
while (len > 0) {
*a = c;
a++;
len--;
}
}
/**
* Find length of string
*/
static size_t sol_strlen(const char *s) {
size_t len = 0;
while (*s) {
len++;
s++;
}
return len;
}
/**
* Internal memory alloc/free function
*/
@SYSCALL void* sol_alloc_free_(uint64_t, void *);
/**
* Alloc zero-initialized memory
*/
static void *sol_calloc(size_t nitems, size_t size) {
return sol_alloc_free_(nitems * size, 0);
}
/**
* Deallocates the memory previously allocated by sol_calloc
*/
static void sol_free(void *ptr) {
(void) sol_alloc_free_(0, ptr);
}
#ifdef __cplusplus
}
#endif
/**@}*/

View File

@ -21,11 +21,15 @@ extern "C" {
* @param bytes_len Number of byte arrays
* @param result 32 byte array to hold the result
*/
uint64_t sol_keccak256(
const SolBytes *bytes,
int bytes_len,
uint8_t *result
);
#ifndef SOL_SBFV2
uint64_t sol_keccak256(const SolBytes *, int, uint8_t *);
#else
typedef uint64_t(*sol_keccak256_pointer_type)(const SolBytes *, int, uint8_t *);
static uint64_t sol_keccak256(const SolBytes * arg1, int arg2, uint8_t * arg3) {
sol_keccak256_pointer_type sol_keccak256_pointer = (sol_keccak256_pointer_type) 3615046331;
return sol_keccak256_pointer(arg1, arg2, arg3);
}
#endif
#ifdef __cplusplus
}

View File

@ -14,19 +14,43 @@ extern "C" {
/**
* Prints a string to stdout
*/
#ifndef SOL_SBFV2
void sol_log_(const char *, uint64_t);
#else
typedef void(*sol_log__pointer_type)(const char *, uint64_t);
static void sol_log_(const char * arg1, uint64_t arg2) {
sol_log__pointer_type sol_log__pointer = (sol_log__pointer_type) 544561597;
sol_log__pointer(arg1, arg2);
}
#endif
#define sol_log(message) sol_log_(message, sol_strlen(message))
/**
* Prints a 64 bit values represented in hexadecimal to stdout
*/
#ifndef SOL_SBFV2
void sol_log_64_(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
#else
typedef void(*sol_log_64__pointer_type)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
static void sol_log_64_(uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5) {
sol_log_64__pointer_type sol_log_64__pointer = (sol_log_64__pointer_type) 1546269048;
sol_log_64__pointer(arg1, arg2, arg3, arg4, arg5);
}
#endif
#define sol_log_64 sol_log_64_
/**
* Prints the current compute unit consumption to stdout
*/
#ifndef SOL_SBFV2
void sol_log_compute_units_();
#else
typedef void(*sol_log_compute_units__pointer_type)();
static void sol_log_compute_units_() {
sol_log_compute_units__pointer_type sol_log_compute_units__pointer = (sol_log_compute_units__pointer_type) 1387942038;
sol_log_compute_units__pointer();
}
#endif
#define sol_log_compute_units() sol_log_compute_units_()
/**
@ -43,7 +67,15 @@ static void sol_log_array(const uint8_t *array, int len) {
/**
* Print the base64 representation of some arrays.
*/
void sol_log_data(SolBytes *fields, uint64_t fields_len);
#ifndef SOL_SBFV2
void sol_log_data(SolBytes *, uint64_t);
#else
typedef void(*sol_log_data_pointer_type)(SolBytes *, uint64_t);
static void sol_log_data(SolBytes * arg1, uint64_t arg2) {
sol_log_data_pointer_type sol_log_data_pointer = (sol_log_data_pointer_type) 1930933300;
sol_log_data_pointer(arg1, arg2);
}
#endif
/**
* Prints the program's input parameters

View File

@ -26,9 +26,15 @@ typedef struct {
*
* @param key The public key to print
*/
void sol_log_pubkey(
const SolPubkey *pubkey
);
#ifndef SOL_SBFV2
void sol_log_pubkey(const SolPubkey *);
#else
typedef void(*sol_log_pubkey_pointer_type)(const SolPubkey *);
static void sol_log_pubkey(const SolPubkey * arg1) {
sol_log_pubkey_pointer_type sol_log_pubkey_pointer = (sol_log_pubkey_pointer_type) 2129692874;
sol_log_pubkey_pointer(arg1);
}
#endif
/**
* Compares two public keys
@ -71,12 +77,15 @@ typedef struct {
* @param program_id Program id of the signer
* @param program_address Program address created, filled on return
*/
uint64_t sol_create_program_address(
const SolSignerSeed *seeds,
int seeds_len,
const SolPubkey *program_id,
SolPubkey *program_address
);
#ifndef SOL_SBFV2
uint64_t sol_create_program_address(const SolSignerSeed *, int, const SolPubkey *, SolPubkey *);
#else
typedef uint64_t(*sol_create_program_address_pointer_type)(const SolSignerSeed *, int, const SolPubkey *, SolPubkey *);
static uint64_t sol_create_program_address(const SolSignerSeed * arg1, int arg2, const SolPubkey * arg3, SolPubkey * arg4) {
sol_create_program_address_pointer_type sol_create_program_address_pointer = (sol_create_program_address_pointer_type) 2474062396;
return sol_create_program_address_pointer(arg1, arg2, arg3, arg4);
}
#endif
/**
* Try to find a program address and return corresponding bump seed
@ -87,13 +96,15 @@ uint64_t sol_create_program_address(
* @param program_address Program address created, filled on return
* @param bump_seed Bump seed required to create a valid program address
*/
uint64_t sol_try_find_program_address(
const SolSignerSeed *seeds,
int seeds_len,
const SolPubkey *program_id,
SolPubkey *program_address,
uint8_t *bump_seed
);
#ifndef SOL_SBFV2
uint64_t sol_try_find_program_address(const SolSignerSeed *, int, const SolPubkey *, SolPubkey *, uint8_t *);
#else
typedef uint64_t(*sol_try_find_program_address_pointer_type)(const SolSignerSeed *, int, const SolPubkey *, SolPubkey *, uint8_t *);
static uint64_t sol_try_find_program_address(const SolSignerSeed * arg1, int arg2, const SolPubkey * arg3, SolPubkey * arg4, uint8_t * arg5) {
sol_try_find_program_address_pointer_type sol_try_find_program_address_pointer = (sol_try_find_program_address_pointer_type) 1213221432;
return sol_try_find_program_address_pointer(arg1, arg2, arg3, arg4, arg5);
}
#endif
#ifdef SOL_TEST
/**

View File

@ -22,7 +22,15 @@ extern "C"
* @param bytes byte array to set
* @param bytes_len length of byte array. This may not exceed MAX_RETURN_DATA.
*/
void sol_set_return_data(const uint8_t *bytes, uint64_t bytes_len);
#ifndef SOL_SBFV2
void sol_set_return_data(const uint8_t *, uint64_t);
#else
typedef void(*sol_set_return_data_pointer_type)(const uint8_t *, uint64_t);
static void sol_set_return_data(const uint8_t * arg1, uint64_t arg2) {
sol_set_return_data_pointer_type sol_set_return_data_pointer = (sol_set_return_data_pointer_type) 2720453611;
sol_set_return_data_pointer(arg1, arg2);
}
#endif
/**
* Get the return data
@ -32,7 +40,15 @@ void sol_set_return_data(const uint8_t *bytes, uint64_t bytes_len);
* @param program_id the program_id which set the return data. Only set if there was some return data (the function returns non-zero).
* @param result length of return data (may exceed bytes_len if the return data is longer)
*/
uint64_t sol_get_return_data(const uint8_t *bytes, uint64_t bytes_len, SolPubkey *program_id);
#ifndef SOL_SBFV2
uint64_t sol_get_return_data(const uint8_t *, uint64_t, SolPubkey *);
#else
typedef uint64_t(*sol_get_return_data_pointer_type)(const uint8_t *, uint64_t, SolPubkey *);
static uint64_t sol_get_return_data(const uint8_t * arg1, uint64_t arg2, SolPubkey * arg3) {
sol_get_return_data_pointer_type sol_get_return_data_pointer = (sol_get_return_data_pointer_type) 1562527204;
return sol_get_return_data_pointer(arg1, arg2, arg3);
}
#endif
#ifdef __cplusplus
}

View File

@ -32,12 +32,15 @@ extern "C" {
* @param result 64 byte array to hold the result. A recovered public key
* @return 0 if executed successfully
*/
uint64_t sol_secp256k1_recover(
const uint8_t *hash,
uint64_t recovery_id,
const uint8_t *signature,
uint8_t *result
);
#ifndef SOL_SBFV2
uint64_t sol_secp256k1_recover(const uint8_t *, uint64_t, const uint8_t *, uint8_t *);
#else
typedef uint64_t(*sol_secp256k1_recover_pointer_type)(const uint8_t *, uint64_t, const uint8_t *, uint8_t *);
static uint64_t sol_secp256k1_recover(const uint8_t * arg1, uint64_t arg2, const uint8_t * arg3, uint8_t * arg4) {
sol_secp256k1_recover_pointer_type sol_secp256k1_recover_pointer = (sol_secp256k1_recover_pointer_type) 400819024;
return sol_secp256k1_recover_pointer(arg1, arg2, arg3, arg4);
}
#endif
#ifdef __cplusplus
}

View File

@ -21,11 +21,15 @@ extern "C" {
* @param bytes_len Number of byte arrays
* @param result 32 byte array to hold the result
*/
uint64_t sol_sha256(
const SolBytes *bytes,
int bytes_len,
uint8_t *result
);
#ifndef SOL_SBFV2
uint64_t sol_sha256(const SolBytes *, int, uint8_t *);
#else
typedef uint64_t(*sol_sha256_pointer_type)(const SolBytes *, int, uint8_t *);
static uint64_t sol_sha256(const SolBytes * arg1, int arg2, uint8_t * arg3) {
sol_sha256_pointer_type sol_sha256_pointer = (sol_sha256_pointer_type) 301243782;
return sol_sha256_pointer(arg1, arg2, arg3);
}
#endif
#ifdef __cplusplus
}

View File

@ -58,7 +58,15 @@ static size_t sol_strlen(const char *s) {
/**
* Internal memory alloc/free function
*/
void *sol_alloc_free_(uint64_t size, void *ptr);
#ifndef SOL_SBFV2
void* sol_alloc_free_(uint64_t, void *);
#else
typedef void*(*sol_alloc_free__pointer_type)(uint64_t, void *);
static void* sol_alloc_free_(uint64_t arg1, void * arg2) {
sol_alloc_free__pointer_type sol_alloc_free__pointer = (sol_alloc_free__pointer_type) 2213547663;
return sol_alloc_free__pointer(arg1, arg2);
}
#endif
/**
* Alloc zero-initialized memory

View File

@ -0,0 +1,14 @@
[package]
name = "gen-headers"
version = "1.11.0"
edition = "2021"
license = "Apache-2.0"
publish = false
[dependencies]
log = { version = "0.4.17", features = ["std"] }
regex = "1.5.4"
[[bin]]
name = "gen-headers"
path = "src/main.rs"

172
sdk/gen-headers/src/main.rs Normal file
View File

@ -0,0 +1,172 @@
#![allow(clippy::integer_arithmetic)]
use {
log::info,
regex::{Captures, Regex},
std::{
ffi::OsStr,
fs,
io::{prelude::*, BufWriter},
path::PathBuf,
str,
},
};
/**
* 1. process every inc file in syscalls header file
*
* 2. in every such file replace the syscall declaration by a new
* declaration with a new extended name, and a static function
* definition that computes a hash of the original name and uses the
* hash to initialize a function pointer, the function pointer then is
* used the call the syscall function.
*/
fn main() {
let syscalls_inc_path = PathBuf::from("sdk/bpf/c/inc/sol/inc");
if syscalls_inc_path.is_dir() {
for entry in fs::read_dir(syscalls_inc_path).expect("Can't open headers dir") {
let entry = entry.expect("Can't open header file");
let path = entry.path();
if !path.is_dir() {
let extension = path.extension();
if extension == Some(OsStr::new("inc")) {
transform(&path);
}
}
}
}
}
/**
* Transform input inc file to a valid C header file replacing
* declaration templates with valid C code.
*/
fn transform(inc: &PathBuf) {
let inc_path = PathBuf::from(inc);
let filename = match inc_path.file_name() {
Some(f) => f,
None => return,
};
let parent = match inc_path.parent() {
Some(f) => f,
None => return,
};
let parent = match parent.parent() {
Some(f) => f,
None => return,
};
let mut header_path = PathBuf::from(parent);
let mut filename = PathBuf::from(filename);
filename.set_extension("h");
header_path.push(filename);
info!(
"Transforming file {} -> {}",
inc.display(),
header_path.display()
);
let mut input = match fs::File::open(inc) {
Ok(x) => x,
Err(err) => panic!("Failed to open {}: {}", inc.display(), err),
};
let mut input_content = vec![];
input.read_to_end(&mut input_content).unwrap();
let input_content = str::from_utf8(&input_content).unwrap();
let output = match fs::File::create(&header_path) {
Ok(x) => x,
Err(err) => panic!("Failed to create {}: {}", header_path.display(), err),
};
let mut output_writer = BufWriter::new(output);
let decl_re =
Regex::new(r"@SYSCALL ([0-9A-Za-z_*]+)[[:space:]]+(sol_[0-9A-Za-z_]+)\(([^);]*)\);")
.unwrap();
let comm_re = Regex::new(r",").unwrap();
let output_content = decl_re.replace_all(input_content, |caps: &Captures| {
let ty = &caps[1].to_string();
let func = &caps[2].to_string();
let args = &caps[3].to_string();
let ifndef = format!("#ifndef SOL_SBFV2\n{} {}({});", ty, func, args);
let hash = sys_hash(func);
let typedef_statement = format!("typedef {}(*{}_pointer_type)({});", ty, func, args);
let mut arg = 0;
let mut arg_list = "".to_string();
if !args.is_empty() {
arg_list = comm_re
.replace_all(args, |_caps: &Captures| {
arg += 1;
format!(" arg{},", arg)
})
.to_string();
arg += 1;
arg_list = format!("{} arg{}", arg_list, arg);
}
let function_signature = format!("static {} {}({})", ty, func, arg_list);
let pointer_assignment = format!(
"{}_pointer_type {}_pointer = ({}_pointer_type) {};",
func, func, func, hash
);
if !args.is_empty() {
arg_list = "arg1".to_string();
for a in 2..arg + 1 {
arg_list = format!("{}, arg{}", arg_list, a);
}
}
let return_statement = if ty == "void" {
format!("{}_pointer({});", func, arg_list)
} else {
format!("return {}_pointer({});", func, arg_list)
};
format!(
"{}\n#else\n{}\n{} {{\n {}\n {}\n}}\n#endif",
ifndef, typedef_statement, function_signature, pointer_assignment, return_statement,
)
});
write!(output_writer, "{}", output_content).unwrap();
}
const fn sys_hash(name: &str) -> usize {
murmur3_32(name.as_bytes(), 0) as usize
}
#[inline(always)]
const fn murmur3_32(buf: &[u8], seed: u32) -> u32 {
let mut hash = seed;
let mut i = 0;
while i < buf.len() / 4 {
let buf = [buf[i * 4], buf[i * 4 + 1], buf[i * 4 + 2], buf[i * 4 + 3]];
hash ^= pre_mix(buf);
hash = hash.rotate_left(13);
hash = hash.wrapping_mul(5).wrapping_add(0xe6546b64);
i += 1;
}
match buf.len() % 4 {
0 => {}
1 => {
hash ^= pre_mix([buf[i * 4], 0, 0, 0]);
}
2 => {
hash ^= pre_mix([buf[i * 4], buf[i * 4 + 1], 0, 0]);
}
3 => {
hash ^= pre_mix([buf[i * 4], buf[i * 4 + 1], buf[i * 4 + 2], 0]);
}
_ => { /* unreachable!() */ }
}
hash ^= buf.len() as u32;
hash ^= hash.wrapping_shr(16);
hash = hash.wrapping_mul(0x85ebca6b);
hash ^= hash.wrapping_shr(13);
hash = hash.wrapping_mul(0xc2b2ae35);
hash ^= hash.wrapping_shr(16);
hash
}
const fn pre_mix(buf: [u8; 4]) -> u32 {
u32::from_le_bytes(buf)
.wrapping_mul(0xcc9e2d51)
.rotate_left(15)
.wrapping_mul(0x1b873593)
}