diff options
Diffstat (limited to 'futility/futility.h')
-rw-r--r-- | futility/futility.h | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/futility/futility.h b/futility/futility.h new file mode 100644 index 00000000..ed268905 --- /dev/null +++ b/futility/futility.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include <stdint.h> + +#ifndef VBOOT_REFERENCE_FUTILITY_H_ +#define VBOOT_REFERENCE_FUTILITY_H_ + +/* + Here's a structure to define the commands that futility implements. + */ +typedef struct { + const char const * name; + int (*handler)(int argc, char **argv); + const char const * shorthelp; +} __attribute__ ((aligned (16))) futil_cmd_t ; /* align for x86_64 ABI */ + +/* + * Create an instance in a separate section. We'll have a linker script to + * gather them all up later, so we can refer to them without explictly + * declaring every function in a header somewhere + */ +#define DECLARE_FUTIL_COMMAND(name, handler, shorthelp) \ + static const char __futil_cmd_name_##name[] = #name; \ + const futil_cmd_t __futil_cmd_##name \ + __attribute__((section(".futil_cmds." #name))) \ + = { __futil_cmd_name_##name, handler, shorthelp } + +/* + * Functions to find the command table. We have to play some games here, + * because the x86_64 ABI says this: + * + * An array uses the same alignment as its elements, except that a local or + * global array variable that requires at least 16 bytes, or a C99 local or + * global variable-length array variable, always has alignment of at least + * 16 bytes. + * + * The linker script doesn't know what alignment to use for __futil_cmds_start, + * because that's determined at compile-time and unavailable to the script + * unless we define one global futil_cmd_t in advance. + */ +static inline futil_cmd_t *futil_cmds_start(void) +{ + extern uintptr_t __futil_cmds_start[]; /* from linker script */ + uintptr_t mask = sizeof(futil_cmd_t) - 1; + uintptr_t addr = (uintptr_t)(__futil_cmds_start); + return (futil_cmd_t *)((addr + mask) & ~mask); +} +static inline futil_cmd_t *futil_cmds_end(void) +{ + extern uintptr_t __futil_cmds_end[]; /* from linker script */ + return (futil_cmd_t *)(&__futil_cmds_end[0]); +} + +#endif /* VBOOT_REFERENCE_FUTILITY_H_ */ |