x86/vdso, build: Make LE access macros clearer, host-safe
authorH. Peter Anvin <hpa@linux.intel.com>
Sat, 31 May 2014 00:03:22 +0000 (17:03 -0700)
committerH. Peter Anvin <hpa@linux.intel.com>
Sat, 31 May 2014 10:35:27 +0000 (03:35 -0700)
Make it a little clearer what the littleendian access macros in
vdso2c.[ch] actually do.  This way they can probably also be moved to
a central location (e.g. tools/include) for the benefit of other host
tools.

We should avoid implementation namespace symbols when writing code
that is compiling for the compiler host, so avoid names starting with
double underscore or underscore-capital.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Link: http://lkml.kernel.org/r/2cf258df123cb24bad63c274c8563c050547d99d.1401464755.git.luto@amacapital.net
arch/x86/vdso/vdso2c.c
arch/x86/vdso/vdso2c.h

index de19ced6c87d69970ba6962a041c0101d3c108c4..deabaf5bfb899d24e1a2f796489f806d55c39b3e 100644 (file)
@@ -54,17 +54,17 @@ static void fail(const char *format, ...)
 /*
  * Evil macros to do a little-endian read.
  */
-#define __GET_TYPE(x, type, bits, ifnot)                               \
+#define GLE(x, bits, ifnot)                                            \
        __builtin_choose_expr(                                          \
-               __builtin_types_compatible_p(typeof(x), type),          \
-               le##bits##toh((x)), ifnot)
+               (sizeof(x) == bits/8),                                  \
+               (__typeof__(x))le##bits##toh(x), ifnot)
 
-extern void bad_get(uint64_t);
+extern void bad_get_le(uint64_t);
+#define LAST_LE(x)                                                     \
+       __builtin_choose_expr(sizeof(x) == 1, (x), bad_get_le(x))
 
-#define GET(x)                                                         \
-       __GET_TYPE((x), __u32, 32, __GET_TYPE((x), __u64, 64,           \
-       __GET_TYPE((x), __s32, 32, __GET_TYPE((x), __s64, 64,           \
-       __GET_TYPE((x), __u16, 16, bad_get(x))))))
+#define GET_LE(x)                                                      \
+       GLE(x, 64, GLE(x, 32, GLE(x, 16, LAST_LE(x))))
 
 #define NSYMS (sizeof(required_syms) / sizeof(required_syms[0]))
 
index f0475dad22867f46655adc04ad88eedb3aa4dbd1..d1e99e1892c4bd85ba16765f7d28ed825bf23edf 100644 (file)
@@ -18,27 +18,27 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
        const char *secstrings;
        uint64_t syms[NSYMS] = {};
 
-       Elf_Phdr *pt = (Elf_Phdr *)(addr + GET(hdr->e_phoff));
+       Elf_Phdr *pt = (Elf_Phdr *)(addr + GET_LE(hdr->e_phoff));
 
        /* Walk the segment table. */
-       for (i = 0; i < GET(hdr->e_phnum); i++) {
-               if (GET(pt[i].p_type) == PT_LOAD) {
+       for (i = 0; i < GET_LE(hdr->e_phnum); i++) {
+               if (GET_LE(pt[i].p_type) == PT_LOAD) {
                        if (found_load)
                                fail("multiple PT_LOAD segs\n");
 
-                       if (GET(pt[i].p_offset) != 0 ||
-                           GET(pt[i].p_vaddr) != 0)
+                       if (GET_LE(pt[i].p_offset) != 0 ||
+                           GET_LE(pt[i].p_vaddr) != 0)
                                fail("PT_LOAD in wrong place\n");
 
-                       if (GET(pt[i].p_memsz) != GET(pt[i].p_filesz))
+                       if (GET_LE(pt[i].p_memsz) != GET_LE(pt[i].p_filesz))
                                fail("cannot handle memsz != filesz\n");
 
-                       load_size = GET(pt[i].p_memsz);
+                       load_size = GET_LE(pt[i].p_memsz);
                        found_load = 1;
-               } else if (GET(pt[i].p_type) == PT_DYNAMIC) {
-                       dyn = addr + GET(pt[i].p_offset);
-                       dyn_end = addr + GET(pt[i].p_offset) +
-                               GET(pt[i].p_memsz);
+               } else if (GET_LE(pt[i].p_type) == PT_DYNAMIC) {
+                       dyn = addr + GET_LE(pt[i].p_offset);
+                       dyn_end = addr + GET_LE(pt[i].p_offset) +
+                               GET_LE(pt[i].p_memsz);
                }
        }
        if (!found_load)
@@ -46,48 +46,51 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
        data_size = (load_size + 4095) / 4096 * 4096;
 
        /* Walk the dynamic table */
-       for (i = 0; dyn + i < dyn_end && GET(dyn[i].d_tag) != DT_NULL; i++) {
-               typeof(dyn[i].d_tag) tag = GET(dyn[i].d_tag);
+       for (i = 0; dyn + i < dyn_end &&
+                    GET_LE(dyn[i].d_tag) != DT_NULL; i++) {
+               typeof(dyn[i].d_tag) tag = GET_LE(dyn[i].d_tag);
                if (tag == DT_REL || tag == DT_RELSZ ||
                    tag == DT_RELENT || tag == DT_TEXTREL)
                        fail("vdso image contains dynamic relocations\n");
        }
 
        /* Walk the section table */
-       secstrings_hdr = addr + GET(hdr->e_shoff) +
-               GET(hdr->e_shentsize)*GET(hdr->e_shstrndx);
-       secstrings = addr + GET(secstrings_hdr->sh_offset);
-       for (i = 0; i < GET(hdr->e_shnum); i++) {
-               Elf_Shdr *sh = addr + GET(hdr->e_shoff) +
-                       GET(hdr->e_shentsize) * i;
-               if (GET(sh->sh_type) == SHT_SYMTAB)
+       secstrings_hdr = addr + GET_LE(hdr->e_shoff) +
+               GET_LE(hdr->e_shentsize)*GET_LE(hdr->e_shstrndx);
+       secstrings = addr + GET_LE(secstrings_hdr->sh_offset);
+       for (i = 0; i < GET_LE(hdr->e_shnum); i++) {
+               Elf_Shdr *sh = addr + GET_LE(hdr->e_shoff) +
+                       GET_LE(hdr->e_shentsize) * i;
+               if (GET_LE(sh->sh_type) == SHT_SYMTAB)
                        symtab_hdr = sh;
 
-               if (!strcmp(secstrings + GET(sh->sh_name), ".altinstructions"))
+               if (!strcmp(secstrings + GET_LE(sh->sh_name),
+                           ".altinstructions"))
                        alt_sec = sh;
        }
 
        if (!symtab_hdr)
                fail("no symbol table\n");
 
-       strtab_hdr = addr + GET(hdr->e_shoff) +
-               GET(hdr->e_shentsize) * GET(symtab_hdr->sh_link);
+       strtab_hdr = addr + GET_LE(hdr->e_shoff) +
+               GET_LE(hdr->e_shentsize) * GET_LE(symtab_hdr->sh_link);
 
        /* Walk the symbol table */
-       for (i = 0; i < GET(symtab_hdr->sh_size) / GET(symtab_hdr->sh_entsize);
+       for (i = 0;
+            i < GET_LE(symtab_hdr->sh_size) / GET_LE(symtab_hdr->sh_entsize);
             i++) {
                int k;
-               Elf_Sym *sym = addr + GET(symtab_hdr->sh_offset) +
-                       GET(symtab_hdr->sh_entsize) * i;
-               const char *name = addr + GET(strtab_hdr->sh_offset) +
-                       GET(sym->st_name);
+               Elf_Sym *sym = addr + GET_LE(symtab_hdr->sh_offset) +
+                       GET_LE(symtab_hdr->sh_entsize) * i;
+               const char *name = addr + GET_LE(strtab_hdr->sh_offset) +
+                       GET_LE(sym->st_name);
                for (k = 0; k < NSYMS; k++) {
                        if (!strcmp(name, required_syms[k])) {
                                if (syms[k]) {
                                        fail("duplicate symbol %s\n",
                                             required_syms[k]);
                                }
-                               syms[k] = GET(sym->st_value);
+                               syms[k] = GET_LE(sym->st_value);
                        }
                }
        }
@@ -147,9 +150,9 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
        fprintf(outfile, "\t},\n");
        if (alt_sec) {
                fprintf(outfile, "\t.alt = %lu,\n",
-                       (unsigned long)GET(alt_sec->sh_offset));
+                       (unsigned long)GET_LE(alt_sec->sh_offset));
                fprintf(outfile, "\t.alt_len = %lu,\n",
-                       (unsigned long)GET(alt_sec->sh_size));
+                       (unsigned long)GET_LE(alt_sec->sh_size));
        }
        for (i = 0; i < NSYMS; i++) {
                if (syms[i])