Skip to content

Commit

Permalink
add checked_struct
Browse files Browse the repository at this point in the history
  • Loading branch information
briansmith committed Oct 4, 2015
1 parent cd5372b commit cd53d14
Show file tree
Hide file tree
Showing 5 changed files with 379 additions and 1 deletion.
92 changes: 92 additions & 0 deletions crypto/ffi.c
@@ -0,0 +1,92 @@
// Copyright 2015 Brian Smith.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#include "ffi.h"

/* Do not include any *ring* headers here other than ffi.h. *ring* headers must
* only be included after the |RING_*_METADATA| macros have been defined near
* the end of this file. */

#include <stddef.h>

struct ring_ffi_struct_metadata {
// Keep in sync with |ring::ffi|.
const char *name;
size_t size;
size_t alignment;

/* The array is terminated by an element with a |NULL| name. */
const struct struct_member_metadata *members;
};

struct ring_ffi_struct_member_metadata {
// Keep in sync with |ring::ffi|.
const char *name;
size_t offset;
};

#if defined(_MSC_VER)
#define RING_ALIGNOF __alignof
#else
#define RING_ALIGNOF _Alignof
#endif

#define RING_META_META_STRUCT(struct_name) \
size_t struct_name##_size(void) { \
return sizeof(struct struct_name); \
} \
\
size_t struct_name##_alignment(void) { \
return RING_ALIGNOF(struct struct_name); \
}

#define RING_META_META_MEMBER(struct_name, member_name) \
size_t struct_name##_##member_name##_offset(void) { \
return offsetof(struct struct_name, member_name); \
}

RING_META_META_STRUCT(ring_ffi_struct_metadata)
RING_META_META_MEMBER(ring_ffi_struct_metadata, name)
RING_META_META_MEMBER(ring_ffi_struct_metadata, size)
RING_META_META_MEMBER(ring_ffi_struct_metadata, alignment)
RING_META_META_MEMBER(ring_ffi_struct_metadata, members)

RING_META_META_STRUCT(ring_ffi_struct_member_metadata)
RING_META_META_MEMBER(ring_ffi_struct_member_metadata, name)
RING_META_META_MEMBER(ring_ffi_struct_member_metadata, offset)

/* These macros are defined in ffi.h to expand to nothing. However, now we need
* them to expand into the definitions of the metadata functions. */

#undef RING_BEGIN_STRUCT_METADATA
#define RING_BEGIN_STRUCT_METADATA(struct_name) \
const struct ring_ffi_struct_metadata \
*ring_ffi_##struct_name##_metadata(void) { \
static const struct ring_ffi_struct_metadata METADATA = { \
#struct_name, \
sizeof(struct struct_name), \
ALIGNOF(struct struct_name), \
{ \

#undef RING_MEMBER_METADATA
#define RING_MEMBER_METADATA(struct_name, member_name) \
{ #member_name, offsetof(struct struct_name, member_name) }

#undef RING_END_STRUCT_METADATA
#define RING_END_STRUCT_METADATA(struct_name) \
{ NULL, 0 } \
} \
}; \
return &METADATA; \
}
58 changes: 58 additions & 0 deletions crypto/ffi.h
@@ -0,0 +1,58 @@
/* Copyright 2015 Brian Smith.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#ifndef RING_HEADER_CRYPTO_FFI_H
#define RING_HEADER_CRYPTO_FFI_H

/* The *ring* FFI consistency interface provides a means for ensuring that
* C and Rust definitions of structs match.
*
* # Example:
*
* ```C
* struct foo_foo {
* // Keep this in sync with |ring::foo::foo| and the metadata below.
* uint64_t bar[12];
* int baz;
* };
*
* RING_BEGIN_STRUCT_METADATA(foo_foo)
* RING_MEMBER_METADATA(foo_foo, bar)
* RING_MEMBER_METADATA(foo_foo, baz)
* RING_END_STRUCT_METADATA(foo_foo)
* ```
*
* ```rust
*
* use libc;
*
* #[macro_use(checked_struct)]
* use ring::ffi;
*
* checked_struct!{
* struct foo_foo {
* bar: [u64; 12],
* baz: libc::c_int,
* },
* test_foo_foo_struct_consistency,
* ring_ffi_foo_foo_metadata
* }
* ```
*/

#define RING_BEGIN_STRUCT_METADATA(struct_name)
#define RING_MEMBER_METADATA(struct_name, member_name)
#define RING_END_STRUCT_METADATA(struct_name)

#endif
3 changes: 2 additions & 1 deletion crypto/libring.Windows.vcxproj
Expand Up @@ -64,6 +64,7 @@
<ClCompile Include="ecdh\ecdh.c" />
<ClCompile Include="ecdsa\ecdsa.c" />
<ClCompile Include="ecdsa\ecdsa_asn1.c" />
<ClCompile Include="ffi.c" />
<ClCompile Include="mem.c" />
<ClCompile Include="modes\cbc.c" />
<ClCompile Include="modes\ctr.c" />
Expand Down Expand Up @@ -110,4 +111,4 @@
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
</Project>
1 change: 1 addition & 0 deletions mk/ring.mk
Expand Up @@ -68,6 +68,7 @@ RING_SRCS = $(addprefix $(RING_PREFIX), \
crypto/ecdh/ecdh.c \
crypto/ecdsa/ecdsa.c \
crypto/ecdsa/ecdsa_asn1.c \
crypto/ffi.c \
crypto/mem.c \
crypto/modes/cbc.c \
crypto/modes/ctr.c \
Expand Down

0 comments on commit cd53d14

Please sign in to comment.