Commit c191920f authored by H. Peter Anvin's avatar H. Peter Anvin

x86/vdso, build: Make LE access macros clearer, host-safe

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: default avatarH. Peter Anvin <hpa@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Link: http://lkml.kernel.org/r/2cf258df123cb24bad63c274c8563c050547d99d.1401464755.git.luto@amacapital.net
parent add4eed0
...@@ -54,17 +54,17 @@ static void fail(const char *format, ...) ...@@ -54,17 +54,17 @@ static void fail(const char *format, ...)
/* /*
* Evil macros to do a little-endian read. * Evil macros to do a little-endian read.
*/ */
#define __GET_TYPE(x, type, bits, ifnot) \ #define GLE(x, bits, ifnot) \
__builtin_choose_expr( \ __builtin_choose_expr( \
__builtin_types_compatible_p(typeof(x), type), \ (sizeof(x) == bits/8), \
le##bits##toh((x)), ifnot) (__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) \ #define GET_LE(x) \
__GET_TYPE((x), __u32, 32, __GET_TYPE((x), __u64, 64, \ GLE(x, 64, GLE(x, 32, GLE(x, 16, LAST_LE(x))))
__GET_TYPE((x), __s32, 32, __GET_TYPE((x), __s64, 64, \
__GET_TYPE((x), __u16, 16, bad_get(x))))))
#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0])) #define NSYMS (sizeof(required_syms) / sizeof(required_syms[0]))
......
...@@ -18,27 +18,27 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name) ...@@ -18,27 +18,27 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
const char *secstrings; const char *secstrings;
uint64_t syms[NSYMS] = {}; 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. */ /* Walk the segment table. */
for (i = 0; i < GET(hdr->e_phnum); i++) { for (i = 0; i < GET_LE(hdr->e_phnum); i++) {
if (GET(pt[i].p_type) == PT_LOAD) { if (GET_LE(pt[i].p_type) == PT_LOAD) {
if (found_load) if (found_load)
fail("multiple PT_LOAD segs\n"); fail("multiple PT_LOAD segs\n");
if (GET(pt[i].p_offset) != 0 || if (GET_LE(pt[i].p_offset) != 0 ||
GET(pt[i].p_vaddr) != 0) GET_LE(pt[i].p_vaddr) != 0)
fail("PT_LOAD in wrong place\n"); 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"); fail("cannot handle memsz != filesz\n");
load_size = GET(pt[i].p_memsz); load_size = GET_LE(pt[i].p_memsz);
found_load = 1; found_load = 1;
} else if (GET(pt[i].p_type) == PT_DYNAMIC) { } else if (GET_LE(pt[i].p_type) == PT_DYNAMIC) {
dyn = addr + GET(pt[i].p_offset); dyn = addr + GET_LE(pt[i].p_offset);
dyn_end = addr + GET(pt[i].p_offset) + dyn_end = addr + GET_LE(pt[i].p_offset) +
GET(pt[i].p_memsz); GET_LE(pt[i].p_memsz);
} }
} }
if (!found_load) if (!found_load)
...@@ -46,48 +46,51 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name) ...@@ -46,48 +46,51 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
data_size = (load_size + 4095) / 4096 * 4096; data_size = (load_size + 4095) / 4096 * 4096;
/* Walk the dynamic table */ /* Walk the dynamic table */
for (i = 0; dyn + i < dyn_end && GET(dyn[i].d_tag) != DT_NULL; i++) { for (i = 0; dyn + i < dyn_end &&
typeof(dyn[i].d_tag) tag = GET(dyn[i].d_tag); 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 || if (tag == DT_REL || tag == DT_RELSZ ||
tag == DT_RELENT || tag == DT_TEXTREL) tag == DT_RELENT || tag == DT_TEXTREL)
fail("vdso image contains dynamic relocations\n"); fail("vdso image contains dynamic relocations\n");
} }
/* Walk the section table */ /* Walk the section table */
secstrings_hdr = addr + GET(hdr->e_shoff) + secstrings_hdr = addr + GET_LE(hdr->e_shoff) +
GET(hdr->e_shentsize)*GET(hdr->e_shstrndx); GET_LE(hdr->e_shentsize)*GET_LE(hdr->e_shstrndx);
secstrings = addr + GET(secstrings_hdr->sh_offset); secstrings = addr + GET_LE(secstrings_hdr->sh_offset);
for (i = 0; i < GET(hdr->e_shnum); i++) { for (i = 0; i < GET_LE(hdr->e_shnum); i++) {
Elf_Shdr *sh = addr + GET(hdr->e_shoff) + Elf_Shdr *sh = addr + GET_LE(hdr->e_shoff) +
GET(hdr->e_shentsize) * i; GET_LE(hdr->e_shentsize) * i;
if (GET(sh->sh_type) == SHT_SYMTAB) if (GET_LE(sh->sh_type) == SHT_SYMTAB)
symtab_hdr = sh; symtab_hdr = sh;
if (!strcmp(secstrings + GET(sh->sh_name), ".altinstructions")) if (!strcmp(secstrings + GET_LE(sh->sh_name),
".altinstructions"))
alt_sec = sh; alt_sec = sh;
} }
if (!symtab_hdr) if (!symtab_hdr)
fail("no symbol table\n"); fail("no symbol table\n");
strtab_hdr = addr + GET(hdr->e_shoff) + strtab_hdr = addr + GET_LE(hdr->e_shoff) +
GET(hdr->e_shentsize) * GET(symtab_hdr->sh_link); GET_LE(hdr->e_shentsize) * GET_LE(symtab_hdr->sh_link);
/* Walk the symbol table */ /* 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++) { i++) {
int k; int k;
Elf_Sym *sym = addr + GET(symtab_hdr->sh_offset) + Elf_Sym *sym = addr + GET_LE(symtab_hdr->sh_offset) +
GET(symtab_hdr->sh_entsize) * i; GET_LE(symtab_hdr->sh_entsize) * i;
const char *name = addr + GET(strtab_hdr->sh_offset) + const char *name = addr + GET_LE(strtab_hdr->sh_offset) +
GET(sym->st_name); GET_LE(sym->st_name);
for (k = 0; k < NSYMS; k++) { for (k = 0; k < NSYMS; k++) {
if (!strcmp(name, required_syms[k])) { if (!strcmp(name, required_syms[k])) {
if (syms[k]) { if (syms[k]) {
fail("duplicate symbol %s\n", fail("duplicate symbol %s\n",
required_syms[k]); 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) ...@@ -147,9 +150,9 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
fprintf(outfile, "\t},\n"); fprintf(outfile, "\t},\n");
if (alt_sec) { if (alt_sec) {
fprintf(outfile, "\t.alt = %lu,\n", 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", 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++) { for (i = 0; i < NSYMS; i++) {
if (syms[i]) if (syms[i])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment