blob: c94ce7349481ae6ae77ab9cfc94aed8476bdf349 [file] [log] [blame]
* 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>
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]);