Add memory allocation support for C programs (#12254)
This commit is contained in:
57
programs/bpf/c/src/alloc/alloc.c
Normal file
57
programs/bpf/c/src/alloc/alloc.c
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
* @brief Example C-based BPF sanity rogram that prints out the parameters
|
||||||
|
* passed to it
|
||||||
|
*/
|
||||||
|
#include <solana_sdk.h>
|
||||||
|
|
||||||
|
extern uint64_t entrypoint(const uint8_t *input) {
|
||||||
|
{
|
||||||
|
// Confirm large allocation fails
|
||||||
|
void *ptr = sol_calloc(1, UINT64_MAX); // TODO use max
|
||||||
|
if (ptr != NULL) {
|
||||||
|
sol_log("Error: Alloc of very larger buffer should fail");
|
||||||
|
sol_panic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Confirm large allocation fails
|
||||||
|
void *ptr = sol_calloc(18446744073709551615U, 1); // TODO use max
|
||||||
|
if (ptr != NULL) {
|
||||||
|
sol_log("Error: Alloc of very larger buffer should fail");
|
||||||
|
sol_panic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test modest allocation and de-allocation
|
||||||
|
void *ptr = sol_calloc(1, 100);
|
||||||
|
if (ptr == NULL) {
|
||||||
|
sol_log("Error: Alloc of 100 bytes failed");
|
||||||
|
sol_panic();
|
||||||
|
}
|
||||||
|
sol_free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Test allocated memory read and write
|
||||||
|
|
||||||
|
const uint64_t iters = 100;
|
||||||
|
uint8_t *ptr = sol_calloc(1, iters);
|
||||||
|
if (ptr == NULL) {
|
||||||
|
sol_log("Error: Alloc failed");
|
||||||
|
sol_panic();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < iters; i++) {
|
||||||
|
*(ptr + i) = i;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < iters; i++) {
|
||||||
|
sol_assert(*(ptr + i) == i);
|
||||||
|
}
|
||||||
|
sol_log_64(0x3, 0, 0, 0, *(ptr + 42));
|
||||||
|
sol_assert(*(ptr + 42) == 42);
|
||||||
|
sol_free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
@ -35,7 +35,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
|||||||
// Test allocated memory read and write
|
// Test allocated memory read and write
|
||||||
|
|
||||||
const ITERS: usize = 100;
|
const ITERS: usize = 100;
|
||||||
let layout = Layout::from_size_align(100, mem::align_of::<u8>()).unwrap();
|
let layout = Layout::from_size_align(ITERS, mem::align_of::<u8>()).unwrap();
|
||||||
let ptr = alloc::alloc::alloc(layout);
|
let ptr = alloc::alloc::alloc(layout);
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
info!("Error: Alloc failed");
|
info!("Error: Alloc failed");
|
||||||
|
@ -107,6 +107,7 @@ fn test_program_bpf_sanity() {
|
|||||||
#[cfg(feature = "bpf_c")]
|
#[cfg(feature = "bpf_c")]
|
||||||
{
|
{
|
||||||
programs.extend_from_slice(&[
|
programs.extend_from_slice(&[
|
||||||
|
("alloc", true),
|
||||||
("bpf_to_bpf", true),
|
("bpf_to_bpf", true),
|
||||||
("multiple_static", true),
|
("multiple_static", true),
|
||||||
("noop", true),
|
("noop", true),
|
||||||
|
@ -49,26 +49,26 @@ static_assert(sizeof(uint64_t) == 8);
|
|||||||
/**
|
/**
|
||||||
* Minimum of signed integral types
|
* Minimum of signed integral types
|
||||||
*/
|
*/
|
||||||
# define INT8_MIN (-128)
|
#define INT8_MIN (-128)
|
||||||
# define INT16_MIN (-32767-1)
|
#define INT16_MIN (-32767-1)
|
||||||
# define INT32_MIN (-2147483647-1)
|
#define INT32_MIN (-2147483647-1)
|
||||||
# define INT64_MIN (-__INT64_C(9223372036854775807)-1)
|
#define INT64_MIN (-9223372036854775807L-1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum of signed integral types
|
* Maximum of signed integral types
|
||||||
*/
|
*/
|
||||||
# define INT8_MAX (127)
|
#define INT8_MAX (127)
|
||||||
# define INT16_MAX (32767)
|
#define INT16_MAX (32767)
|
||||||
# define INT32_MAX (2147483647)
|
#define INT32_MAX (2147483647)
|
||||||
# define INT64_MAX (__INT64_C(9223372036854775807))
|
#define INT64_MAX (9223372036854775807L)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum of unsigned integral types
|
* Maximum of unsigned integral types
|
||||||
*/
|
*/
|
||||||
# define UINT8_MAX (255)
|
#define UINT8_MAX (255)
|
||||||
# define UINT16_MAX (65535)
|
#define UINT16_MAX (65535)
|
||||||
# define UINT32_MAX (4294967295U)
|
#define UINT32_MAX (4294967295U)
|
||||||
# define UINT64_MAX (__UINT64_C(18446744073709551615))
|
#define UINT64_MAX (18446744073709551615UL)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NULL
|
* NULL
|
||||||
@ -227,6 +227,26 @@ static size_t sol_strlen(const char *s) {
|
|||||||
*/
|
*/
|
||||||
#define SOL_ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
#define SOL_ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal memory alloc/free function
|
||||||
|
*/
|
||||||
|
void *sol_alloc_free_(uint64_t size, void *ptr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Panics
|
* Panics
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user