Skip to content

Commit

Permalink
ffi: use patched cbindgen
Browse files Browse the repository at this point in the history
I've implemented #[repr(packed)] and #[repr(align(...))] support in
cbindgen[1], and the new binary no longer requires the hacks I had to
previously apply.

[1]: mozilla/cbindgen#431

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
  • Loading branch information
cyphar committed Dec 15, 2019
1 parent 3df77c8 commit b148ddd
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 64 deletions.
20 changes: 3 additions & 17 deletions cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,6 @@ autogen_warning = """
*/
"""

# Part of workaround for https://github.com/eqrion/cbindgen/issues/430.
trailer = """
#ifndef LIBPATHRS_H___CBINDGEN_430_WORKAROUND
#define LIBPATHRS_H___CBINDGEN_430_WORKAROUND
/* Part of workaround for https://github.com/eqrion/cbindgen/issues/430. */
struct pathrs_config_global_t {
bool error_backtraces;
} __attribute__((packed));
struct pathrs_config_root_t {
pathrs_resolver_t resolver;
} __attribute__((packed));
#endif /* LIBPATHRS_H___CBINDGEN_430_WORKAROUND */
"""

# Needed for dev_t.
sys_includes = ["sys/types.h"]

Expand All @@ -76,6 +61,9 @@ line_length = 80
tab_width = 4
style = "type"

[layout]
packed = "__attribute__((packed))"

[export]
exclude = [
# Useless for C users.
Expand All @@ -96,8 +84,6 @@ exclude = [
include = [
"CGlobalConfig",
"CRootConfig",
# Part of workaround for https://github.com/eqrion/cbindgen/issues/430.
"CResolver",
]

# Clean up the naming of structs.
Expand Down
28 changes: 10 additions & 18 deletions contrib/bindings/python/pathrs.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,25 +339,17 @@ def __do_load():
# wrote this. :P
packed_hdr = ""
for struct in packed_structs:
patterns = [
# struct definition
re.compile("^\s*struct\s+%s[\s\n]*{[^}]*}\s*;?" % (struct,), flags=re.MULTILINE),
# typedef
# TODO: This will absolutely break after we fix the cbindgen
# limitations (this won't handle "typedef struct { ... } foo"
# even remotely correctly).
re.compile("^\s*typedef\s+[^;{]*%s[^;{]*;" % (struct,), flags=re.MULTILINE),
]

for pattern in patterns:
# Add the matched pattern to the packed header.
try:
packed_hdr += re.search(pattern, hdr).group() + "\n"
except:
raise RuntimeError("pathrs.h invalid -- packed-struct=%s listed but struct not defined" % (struct,))
# struct definition
pattern = re.compile("^typedef\s*struct[^{;]+{[^}]*}\s*%s\s*;?" % (struct,), flags=re.MULTILINE)

# Add the matched pattern to the packed header.
try:
packed_hdr += re.search(pattern, hdr).group() + "\n"
except:
raise RuntimeError("pathrs.h invalid -- packed-struct=%s listed but struct not defined" % (struct,))

# And drop it from the original header.
hdr = re.sub(pattern, "", hdr)
# And drop it from the original header.
hdr = re.sub(pattern, "", hdr)

ffi.cdef("typedef uint32_t dev_t;")
ffi.cdef(hdr)
Expand Down
53 changes: 26 additions & 27 deletions include/pathrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
* The type of object being passed to "object agnostic" libpathrs functions.
*/
typedef enum {
__INVALID = 0,
__PATHRS_INVALID_TYPE = 0,
/**
* NULL.
*/
Expand All @@ -69,7 +69,7 @@ typedef enum {
* resolver for a `pathrs_root_t`.
*/
typedef enum {
__INVALID = 0,
__PATHRS_INVALID_RESOLVER = 0,
/**
* Use the native openat2(2) backend (requires kernel support).
*/
Expand All @@ -80,12 +80,6 @@ typedef enum {
PATHRS_EMULATED_RESOLVER = 61441,
} pathrs_resolver_t;

/**
* Global configuration for pathrs, for use with
* `pathrs_configure(PATHRS_NONE, NULL)`
*/
typedef struct pathrs_config_global_t pathrs_config_global_t;

/**
* This is only exported to work around a Rust compiler restriction. Consider
* it an implementation detail and don't make use of it.
Expand All @@ -98,12 +92,6 @@ typedef struct __pathrs_handle_t __pathrs_handle_t;
*/
typedef struct __pathrs_root_t __pathrs_root_t;

/**
* Configuration for a specific `pathrs_root_t`, for use with
* `pathrs_configure(PATHRS_ROOT, <root>)`
*/
typedef struct pathrs_config_root_t pathrs_config_root_t;

/**
* Represents a single entry in a Rust backtrace in C. This structure is
* owned by the relevant `pathrs_error_t`.
Expand Down Expand Up @@ -204,6 +192,30 @@ typedef __pathrs_handle_t pathrs_handle_t;
*/
typedef __pathrs_root_t pathrs_root_t;

/**
* Global configuration for pathrs, for use with
* `pathrs_configure(PATHRS_NONE, NULL)`
*/
typedef struct __attribute__((packed)) {
/**
* Sets whether backtraces will be generated for errors. This is a global
* setting, and defaults to **disabled** for release builds of libpathrs
* (but is **enabled** for debug builds).
*/
bool error_backtraces;
} pathrs_config_global_t;

/**
* Configuration for a specific `pathrs_root_t`, for use with
* `pathrs_configure(PATHRS_ROOT, <root>)`
*/
typedef struct __attribute__((packed)) {
/**
* Resolver used for all resolution under this `pathrs_root_t`.
*/
pathrs_resolver_t resolver;
} pathrs_config_root_t;

/**
* Configure pathrs and its objects and fetch the current configuration.
*
Expand Down Expand Up @@ -333,16 +345,3 @@ pathrs_handle_t *pathrs_resolve(pathrs_root_t *root, const char *path);
int pathrs_symlink(pathrs_root_t *root, const char *path, const char *target);

#endif /* LIBPATHRS_H */

#ifndef LIBPATHRS_H___CBINDGEN_430_WORKAROUND
#define LIBPATHRS_H___CBINDGEN_430_WORKAROUND
/* Part of workaround for https://github.com/eqrion/cbindgen/issues/430. */
struct pathrs_config_global_t {
bool error_backtraces;
} __attribute__((packed));

struct pathrs_config_root_t {
pathrs_resolver_t resolver;
} __attribute__((packed));
#endif /* LIBPATHRS_H___CBINDGEN_430_WORKAROUND */

4 changes: 2 additions & 2 deletions src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ trait CConfig {
#[allow(non_camel_case_types, dead_code)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum CResolver {
__INVALID = 0,
__PATHRS_INVALID_RESOLVER = 0,
/// Use the native openat2(2) backend (requires kernel support).
PATHRS_KERNEL_RESOLVER = 0xF000,
/// Use the userspace "emulated" backend.
Expand Down Expand Up @@ -829,7 +829,7 @@ pub extern "C" fn pathrs_configure(
#[allow(non_camel_case_types, dead_code)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum CPointerType {
__INVALID = 0,
__PATHRS_INVALID_TYPE = 0,
/// NULL.
PATHRS_NONE = 0xDFFF,
/// `pathrs_error_t`
Expand Down

0 comments on commit b148ddd

Please sign in to comment.