summaryrefslogtreecommitdiff
path: root/futility/futility.h
diff options
context:
space:
mode:
Diffstat (limited to 'futility/futility.h')
-rw-r--r--futility/futility.h57
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_ */