Remove need to use null when passing Rust strings (#4756)

This commit is contained in:
Jack May 2019-06-20 19:09:50 -07:00 committed by GitHub
parent ada4d16c4c
commit 425ac8d520
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 15 deletions

View File

@ -28,6 +28,8 @@ use std::ffi::CStr;
use std::io::prelude::*;
use std::io::{Error, ErrorKind};
use std::mem;
use std::slice::from_raw_parts;
use std::str::from_utf8;
/// Program heap allocators are intended to allocate/free from a given
/// chunk of memory. The specific allocator implementation is
@ -139,8 +141,7 @@ pub fn helper_sol_panic(
}
/// Logging helper functions, called when the BPF program calls `sol_log_()` or
/// `sol_log_64_()`. Both functions use a common verify function to validate
/// their parameters.
/// `sol_log_64_()`.
pub fn helper_sol_log_verify(
addr: u64,
_arg2: u64,
@ -169,6 +170,39 @@ pub fn helper_sol_log(
};
0
}
pub fn helper_sol_log_verify_(
addr: u64,
len: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
_context: &mut Option<Box<Any + 'static>>,
ro_regions: &[MemoryRegion],
_rw_regions: &[MemoryRegion],
) -> Result<(()), Error> {
for region in ro_regions.iter() {
if region.addr <= addr && (addr as u64) + len <= region.addr + region.len {
return Ok(());
}
}
Err(Error::new(
ErrorKind::Other,
"Error: Load segfault, bad string pointer",
))
}
pub fn helper_sol_log_(
addr: u64,
len: u64,
_arg3: u64,
_arg4: u64,
_arg5: u64,
_context: &mut Option<Box<Any + 'static>>,
) -> u64 {
let ptr: *const u8 = addr as *const u8;
let message = unsafe { from_utf8(from_raw_parts(ptr, len as usize)) };
info!("sol_log: {:?}", message);
0
}
pub fn helper_sol_log_u64(
arg1: u64,
arg2: u64,
@ -238,8 +272,8 @@ pub fn create_vm(prog: &[u8]) -> Result<(EbpfVmRaw, MemoryRegion), Error> {
vm.register_helper_ex("sol_log", Some(helper_sol_log_verify), helper_sol_log, None)?;
vm.register_helper_ex(
"sol_log_",
Some(helper_sol_log_verify),
helper_sol_log,
Some(helper_sol_log_verify_),
helper_sol_log_,
None,
)?;
vm.register_helper_ex("sol_log_64", None, helper_sol_log_u64, None)?;

View File

@ -27,22 +27,13 @@ macro_rules! info {
/// Prints a string to stdout
///
/// @param message - Message to print
#[inline(never)] // prevent inline so everyone does not incur stack cost
pub fn sol_log(message: &str) {
// Not pretty but 1/3 faster then using `clone_from_slice()`
let mut buf: [u8; 128] = [0; 128];
for (i, b) in message.as_bytes().iter().enumerate() {
if i > 127 {
break;
}
buf[i] = *b;
}
unsafe {
sol_log_(buf.as_ptr());
sol_log_(message.as_ptr(), message.len() as u64);
}
}
extern "C" {
fn sol_log_(message: *const u8);
fn sol_log_(message: *const u8, length: u64);
}
/// Prints 64 bit values represented as hexadecimal to stdout