Skip to content

Commit 7b99784

Browse files
committed
Add AligneType and redo secp256k1_context_create with alloc
1 parent 11e9641 commit 7b99784

File tree

3 files changed

+46
-21
lines changed

3 files changed

+46
-21
lines changed

secp256k1-sys/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ features = [ "recovery", "endomorphism", "lowmemory" ]
2121
[build-dependencies]
2222
cc = "1.0.28"
2323

24+
[dev-dependencies]
25+
libc = "0.2"
26+
2427
[features]
2528
default = ["std"]
2629
recovery = []

secp256k1-sys/src/lib.rs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -534,19 +534,21 @@ extern "C" {
534534
#[no_mangle]
535535
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
536536
pub unsafe extern "C" fn rustsecp256k1_v0_3_1_context_create(flags: c_uint) -> *mut Context {
537-
use std::mem;
538-
assert!(mem::align_of::<usize>() >= mem::align_of::<u8>());
539-
assert_eq!(mem::size_of::<usize>(), mem::size_of::<&usize>());
540-
541-
let word_size = mem::size_of::<usize>();
542-
let n_words = (secp256k1_context_preallocated_size(flags) + word_size - 1) / word_size;
543-
544-
let buf = vec![0usize; n_words + 1].into_boxed_slice();
545-
let ptr = Box::into_raw(buf) as *mut usize;
546-
::core::ptr::write(ptr, n_words);
547-
let ptr: *mut usize = ptr.offset(1);
548-
549-
secp256k1_context_preallocated_create(ptr as *mut c_void, flags)
537+
use core::mem;
538+
use std::alloc;
539+
assert!(ALIGN_TO >= mem::align_of::<usize>());
540+
assert!(ALIGN_TO >= mem::align_of::<&usize>());
541+
assert!(ALIGN_TO >= mem::size_of::<usize>());
542+
543+
// We need to allocate `ALIGN_TO` more bytes in order to write the amount of bytes back.
544+
let bytes = secp256k1_context_preallocated_size(flags) + ALIGN_TO;
545+
let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
546+
let ptr = alloc::alloc(layout);
547+
(ptr as *mut usize).write(bytes);
548+
// We must offset a whole ALIGN_TO in order to preserve the same alignment
549+
// this means we "lose" ALIGN_TO-size_of(usize) for padding.
550+
let ptr = ptr.add(ALIGN_TO) as *mut c_void;
551+
secp256k1_context_preallocated_create(ptr, flags)
550552
}
551553

552554
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
@@ -563,13 +565,12 @@ pub unsafe fn secp256k1_context_create(flags: c_uint) -> *mut Context {
563565
#[no_mangle]
564566
#[cfg(all(feature = "std", not(feature = "external-symbols")))]
565567
pub unsafe extern "C" fn rustsecp256k1_v0_3_1_context_destroy(ctx: *mut Context) {
568+
use std::alloc;
566569
secp256k1_context_preallocated_destroy(ctx);
567-
let ctx: *mut usize = ctx as *mut usize;
568-
569-
let n_words_ptr: *mut usize = ctx.offset(-1);
570-
let n_words: usize = ::core::ptr::read(n_words_ptr);
571-
let slice: &mut [usize] = slice::from_raw_parts_mut(n_words_ptr , n_words+1);
572-
let _ = Box::from_raw(slice as *mut [usize]);
570+
let ptr = (ctx as *mut u8).sub(ALIGN_TO);
571+
let bytes = (ptr as *mut usize).read();
572+
let layout = alloc::Layout::from_size_align(bytes, ALIGN_TO).unwrap();
573+
alloc::dealloc(ptr, layout);
573574
}
574575

575576
#[cfg(all(feature = "std", not(feature = "external-symbols")))]

secp256k1-sys/src/types.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![allow(non_camel_case_types)]
2-
use core::fmt;
2+
use core::{fmt, mem};
33

44
pub type c_int = i32;
55
pub type c_uchar = u8;
@@ -26,18 +26,39 @@ impl fmt::Debug for c_void {
2626
}
2727
}
2828

29+
/// A type that is as aligned as the biggest alignment for fundamental types in C
30+
/// since C11 that means as aligned as `max_align_t` is.
31+
/// the exact size/alignment is unspecified.
32+
// 16 matches is as big as the biggest alignment in any arch that rust currently supports https://github.com/rust-lang/rust/blob/2c31b45ae878b821975c4ebd94cc1e49f6073fd0/library/std/src/sys_common/alloc.rs
33+
#[repr(align(16))]
34+
#[derive(Default, Copy, Clone)]
35+
pub struct AlignedType([u8; 16]);
36+
37+
impl AlignedType {
38+
pub fn zeroed() -> Self {
39+
AlignedType([0u8; 16])
40+
}
41+
}
42+
43+
pub(crate) const ALIGN_TO: usize = mem::align_of::<AlignedType>();
44+
45+
2946
#[cfg(test)]
3047
mod tests {
48+
extern crate libc;
3149
use std::os::raw;
50+
use std::mem;
3251
use std::any::TypeId;
33-
use types;
52+
use {types, AlignedType};
3453

3554
#[test]
3655
fn verify_types() {
3756
assert_eq!(TypeId::of::<types::c_int>(), TypeId::of::<raw::c_int>());
3857
assert_eq!(TypeId::of::<types::c_uchar>(), TypeId::of::<raw::c_uchar>());
3958
assert_eq!(TypeId::of::<types::c_uint>(), TypeId::of::<raw::c_uint>());
4059
assert_eq!(TypeId::of::<types::c_char>(), TypeId::of::<raw::c_char>());
60+
61+
assert!(mem::align_of::<AlignedType>() >= mem::align_of::<self::libc::max_align_t>());
4162
}
4263
}
4364

0 commit comments

Comments
 (0)