diff options
author | Bill Richardson <wfrichar@chromium.org> | 2014-07-12 10:46:56 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-07-15 21:21:24 +0000 |
commit | 7d028c4f03c82307fc17dd1226c9949bdbbf38d1 (patch) | |
tree | 4bf8514ea22ea05567670f4d3964a7da552735e6 | |
parent | 71dc66a9b3b3945eebedb0440933aea1c693af95 (diff) | |
download | vboot-7d028c4f03c82307fc17dd1226c9949bdbbf38d1.tar.gz |
Simplify the futility linker script a bit.
The alignment rules were complicated and not always correct. This change
sorts pointers instead of structures, and aligns the pointer table better.
BUG=chromium:224734
BRANCH=ToT
TEST=make runtests
Change-Id: I16c4e9b777fffe7537127aba15413b54e8e0f0a4
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/207717
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | futility/futility.c | 20 | ||||
-rw-r--r-- | futility/futility.h | 57 | ||||
-rw-r--r-- | futility/futility.lds | 5 |
3 files changed, 32 insertions, 50 deletions
diff --git a/futility/futility.c b/futility/futility.c index 35620865..52c2d7dd 100644 --- a/futility/futility.c +++ b/futility/futility.c @@ -56,17 +56,17 @@ must be located in a directory named \"" SUBDIR "\" underneath\n\ the " MYNAME " executable.\n\ \n"; -static int help(int argc, char *argv[]) +static int do_help(int argc, char *argv[]) { - futil_cmd_t *cmd; + struct futil_cmd_t **cmd; int i; fputs(usage, stdout); printf("The following commands are built-in:\n"); - for (cmd = futil_cmds_start(); cmd < futil_cmds_end(); cmd++) - printf(" %-20s %s\n", cmd->name, cmd->shorthelp); + for (cmd = futil_cmds; *cmd; cmd++) + printf(" %-20s %s\n", (*cmd)->name, (*cmd)->shorthelp); printf("\n"); if (argc) { @@ -77,7 +77,7 @@ static int help(int argc, char *argv[]) return 0; } -DECLARE_FUTIL_COMMAND(help, help, "show a bit of help"); +DECLARE_FUTIL_COMMAND(help, do_help, "show a bit of help"); /******************************************************************************/ @@ -209,7 +209,7 @@ int main(int argc, char *argv[], char *envp[]) pid_t myproc; ssize_t r; char *s; - futil_cmd_t *cmd; + struct futil_cmd_t **cmd; log_args(argc, argv); @@ -223,7 +223,7 @@ int main(int argc, char *argv[], char *envp[]) /* Invoked directly by name */ if (0 == strcmp(progname, MYNAME) || 0 == strcmp(progname, MYNAME_S)) { if (argc < 2) { /* must have an argument */ - help(0, 0); + do_help(0, 0); exit(1); } @@ -240,9 +240,9 @@ int main(int argc, char *argv[], char *envp[]) } /* See if it's asking for something we know how to do ourselves */ - for (cmd = futil_cmds_start(); cmd < futil_cmds_end(); cmd++) - if (0 == strcmp(cmd->name, progname)) - return cmd->handler(argc, argv); + for (cmd = futil_cmds; *cmd; cmd++) + if (0 == strcmp((*cmd)->name, progname)) + return (*cmd)->handler(argc, argv); /* Nope, it must be wrapped */ diff --git a/futility/futility.h b/futility/futility.h index c94ce734..005a0ce7 100644 --- a/futility/futility.h +++ b/futility/futility.h @@ -8,50 +8,31 @@ #ifndef VBOOT_REFERENCE_FUTILITY_H_ #define VBOOT_REFERENCE_FUTILITY_H_ -/* - Here's a structure to define the commands that futility implements. - */ -typedef struct { +/* Here's a structure to define the commands that futility implements. */ +struct futil_cmd_t { 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. + * Macro to define a command. * - * 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. + * This defines the struct, then puts a pointer to it in a separate section. + * We'll have a linker script to gather the pointers up later, so we can refer + * to them without explictly declaring every function in a header somewhere. */ -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]); -} +#define DECLARE_FUTIL_COMMAND(NAME, HANDLER, SHORTHELP) \ + static struct futil_cmd_t cmd_##NAME = { \ + .name = #NAME, \ + .handler = HANDLER, \ + .shorthelp = SHORTHELP \ + }; \ + const struct futil_cmd_t *__cmd_ptr_##NAME \ + __attribute__((section(".futil_cmds." #NAME))) \ + = &cmd_##NAME + +/* This is the list of pointers to all commands. */ +extern struct futil_cmd_t *futil_cmds[]; #endif /* VBOOT_REFERENCE_FUTILITY_H_ */ diff --git a/futility/futility.lds b/futility/futility.lds index e03ab5c4..0650507f 100644 --- a/futility/futility.lds +++ b/futility/futility.lds @@ -7,8 +7,9 @@ SECTIONS { .rodata : { - __futil_cmds_start = .; + . = ALIGN(32); + futil_cmds = .; /* Create the list of commands */ *(SORT(.futil_cmds.*)); - __futil_cmds_end = .; + QUAD(0); /* Null-terminated */ } } |