/* * 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 #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_ */