summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2014-07-12 10:46:56 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-07-15 21:21:24 +0000
commit7d028c4f03c82307fc17dd1226c9949bdbbf38d1 (patch)
tree4bf8514ea22ea05567670f4d3964a7da552735e6
parent71dc66a9b3b3945eebedb0440933aea1c693af95 (diff)
downloadvboot-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.c20
-rw-r--r--futility/futility.h57
-rw-r--r--futility/futility.lds5
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 */
}
}