On this page:
5.1 Headers
header?
make-header
header
5.2 Compilation
compile-header
query?
query:  sizeof
query:  offset
query:  expr
system-compiler
5.3 Layouts
layout?
primitive-layout?
ref-layout?
struct-layout?
union-layout?
array-layout?
pointer-layout?
enum-layout?
layout-size
layout-offset
struct-layout-lookup
union-layout-lookup
deref-layout
5.4 Application Binary Interfaces (ABI’s)
abi
abi-lookup
abi-lookup-typedef
abi-lookup-tag
serialize-abi
deserialize-abi
read-abi
write-abi

5 Header Compilation

This library provides facilities for extracting and compiling C header information to generate architecture-specific binary layout information. This is particularly useful for writing code that interacts with the PLT Scheme foreign library—see The Racket Foreign Interface.

Specifically, the foreign library’s pointer-manipulation procedures such as ptr-ref and ptr-set! can be used to read and write to arbitrary addresses, which can be computed using layout information.

 (require c/header) package: c-utils

5.1 Headers

procedure

(header? x)  boolean?

  x : any
Determines whether x is a header.

procedure

(make-header components)  header?

  components : (listof (or/c decl? header?))
Constructs a header.

procedure

(header component ...+)  header?

  component : (or/c decl? header?)
Constructs a header.

Examples:
> (define example.h
    (make-header (include/reader "example.h"
                                 (make-program-reader))))

make-program-reader: undefined;

 cannot reference undefined identifier

> (define time.h
    (header
     (struct tm ([int tm_sec]
                 [int tm_min]
                 [int tm_hour]
                 [int tm_mday]
                 [int tm_mon]
                 [int tm_year]
                 [int tm_wday]
                 [int tm_yday]
                 [int tm_isdst]))))

Using the Scribble @-reader, the latter example could be rewritten with embedded C syntax as:

(define time.h
  (make-header
   @program{
     struct tm {
         int tm_sec;
         int tm_min;
         int tm_hour;
         int tm_mday;
         int tm_mon;
         int tm_year;
         int tm_wday;
         int tm_yday;
         int tm_isdst;
     };
   }))

5.2 Compilation

procedure

(compile-header header compiler)  abi?

  header : header?
  compiler : ((listof query?) -> (listof uint))
Compiles header using the given compiler, producing an ABI. See Application Binary Interfaces (ABI’s).

A header compiler must recognize the following types of queries.

procedure

(query? x)  boolean?

  x : any
Determines whether x is a query

struct

(struct query:sizeof (type)
    #:extra-constructor-name make-query:sizeof)
  type : any
A query to determine the size of the type represented by type.

struct

(struct query:offset (type field)
    #:extra-constructor-name make-query:offset)
  type : any
  field : symbol?
A query to determine the offset of field in type.

struct

(struct query:expr (expr)
    #:extra-constructor-name make-query:expr)
  expr : any
A query to determine the value of the integer expression expr.

procedure

(system-compiler [#:include<> include<> 
  #:include include 
  exe]) 
  ((listof query?) -> (listof uint))
  include<> : (listof string?) = '()
  include : (listof string?) = '()
  exe : ((-> any) -> any) = gcc
A header compiler that delegates to an external C compiler, presumably installed on the current system. The queries are converted into a series of C statements which are assembled into a C program that produces the answers. The include<> list is used to generate the list of system C headers to be included in the generated C program, and the include list is the list of path strings for local headers included in the generated C program. The gcc compiler is used by default, but this can be overridden by providing an alternative system compiler for the exe argument.

5.3 Layouts

procedure

(layout? x)  boolean?

  x : any

procedure

(primitive-layout? x)  boolean?

  x : layout?

procedure

(ref-layout? x)  boolean?

  x : layout?

procedure

(struct-layout? x)  boolean?

  x : layout?

procedure

(union-layout? x)  boolean?

  x : layout?

procedure

(array-layout? x)  boolean?

  x : layout?

procedure

(pointer-layout? x)  boolean?

  x : layout?

procedure

(enum-layout? x)  boolean?

  x : layout?

procedure

(layout-size x)  uint

  x : layout?

procedure

(layout-offset x path)  uint

  x : (or/c struct-layout? union-layout? enum-layout?)
  path : (or/c symbol? (listof symbol?))

procedure

(struct-layout-lookup x name)  layout?

  x : struct-layout?
  name : symbol?

procedure

(union-layout-lookup x name)  layout?

  x : union-layout?
  name : symbol?

procedure

(deref-layout x)  layout?

  x : layout?

5.4 Application Binary Interfaces (ABI’s)

An Application Binary Interface (ABI) provides information about the binary representation of C datatypes on a particular architecture.

struct

(struct abi (typedefs tags)
    #:extra-constructor-name make-abi)
  typedefs : (hasheqof symbol? layout?)
  tags : (hasheqof symbol? layout?)
An ABI. The typedefs are a table of type definitions and the tags are a table of struct, union, and enum tag definitions.

As a convenience, ABI structures can be used as procedures, which is equivalent to calling abi-lookup with the ABI structure as the first argument.

procedure

(abi-lookup abi name)  layout?

  abi : abi?
  name : symbol?
Looks up the definition of name in abi, searching the type definitions first, and failing that, the tag definitions.

procedure

(abi-lookup-typedef abi name)  layout?

  abi : abi?
  name : symbol?
Looks up the type definition of name in abi.

procedure

(abi-lookup-tag abi name)  layout?

  abi : abi?
  name : symbol?
Looks up the type tag definition of name in abi.

procedure

(serialize-abi abi)  sexp?

  abi : abi?
Serializes abi as an S-expression.

procedure

(deserialize-abi input)  abi?

  input : sexp?
Deserializes input as a representation of an ABI.

procedure

(read-abi [in])  abi?

  in : input-port? = (current-input-port)
Reads a serialized ABI from in.

procedure

(write-abi abi [out])  any

  abi : abi?
  out : output-port? = (current-output-port)
Serializes abi and writes it to out.