aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/vdso/vdso2c.c16
-rw-r--r--arch/x86/vdso/vdso2c.h65
2 files changed, 42 insertions, 39 deletions
diff --git a/arch/x86/vdso/vdso2c.c b/arch/x86/vdso/vdso2c.c
index de19ced6c87d..deabaf5bfb89 100644
--- a/arch/x86/vdso/vdso2c.c
+++ b/arch/x86/vdso/vdso2c.c
@@ -54,17 +54,17 @@ static void fail(const char *format, ...)
54/* 54/*
55 * Evil macros to do a little-endian read. 55 * Evil macros to do a little-endian read.
56 */ 56 */
57#define __GET_TYPE(x, type, bits, ifnot) \ 57#define GLE(x, bits, ifnot) \
58 __builtin_choose_expr( \ 58 __builtin_choose_expr( \
59 __builtin_types_compatible_p(typeof(x), type), \ 59 (sizeof(x) == bits/8), \
60 le##bits##toh((x)), ifnot) 60 (__typeof__(x))le##bits##toh(x), ifnot)
61 61
62extern void bad_get(uint64_t); 62extern void bad_get_le(uint64_t);
63#define LAST_LE(x) \
64 __builtin_choose_expr(sizeof(x) == 1, (x), bad_get_le(x))
63 65
64#define GET(x) \ 66#define GET_LE(x) \
65 __GET_TYPE((x), __u32, 32, __GET_TYPE((x), __u64, 64, \ 67 GLE(x, 64, GLE(x, 32, GLE(x, 16, LAST_LE(x))))
66 __GET_TYPE((x), __s32, 32, __GET_TYPE((x), __s64, 64, \
67 __GET_TYPE((x), __u16, 16, bad_get(x))))))
68 68
69#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0])) 69#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0]))
70 70
diff --git a/arch/x86/vdso/vdso2c.h b/arch/x86/vdso/vdso2c.h
index f0475dad2286..d1e99e1892c4 100644
--- a/arch/x86/vdso/vdso2c.h
+++ b/arch/x86/vdso/vdso2c.h
@@ -18,27 +18,27 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
18 const char *secstrings; 18 const char *secstrings;
19 uint64_t syms[NSYMS] = {}; 19 uint64_t syms[NSYMS] = {};
20 20
21 Elf_Phdr *pt = (Elf_Phdr *)(addr + GET(hdr->e_phoff)); 21 Elf_Phdr *pt = (Elf_Phdr *)(addr + GET_LE(hdr->e_phoff));
22 22
23 /* Walk the segment table. */ 23 /* Walk the segment table. */
24 for (i = 0; i < GET(hdr->e_phnum); i++) { 24 for (i = 0; i < GET_LE(hdr->e_phnum); i++) {
25 if (GET(pt[i].p_type) == PT_LOAD) { 25 if (GET_LE(pt[i].p_type) == PT_LOAD) {
26 if (found_load) 26 if (found_load)
27 fail("multiple PT_LOAD segs\n"); 27 fail("multiple PT_LOAD segs\n");
28 28
29 if (GET(pt[i].p_offset) != 0 || 29 if (GET_LE(pt[i].p_offset) != 0 ||
30 GET(pt[i].p_vaddr) != 0) 30 GET_LE(pt[i].p_vaddr) != 0)
31 fail("PT_LOAD in wrong place\n"); 31 fail("PT_LOAD in wrong place\n");
32 32
33 if (GET(pt[i].p_memsz) != GET(pt[i].p_filesz)) 33 if (GET_LE(pt[i].p_memsz) != GET_LE(pt[i].p_filesz))
34 fail("cannot handle memsz != filesz\n"); 34 fail("cannot handle memsz != filesz\n");
35 35
36 load_size = GET(pt[i].p_memsz); 36 load_size = GET_LE(pt[i].p_memsz);
37 found_load = 1; 37 found_load = 1;
38 } else if (GET(pt[i].p_type) == PT_DYNAMIC) { 38 } else if (GET_LE(pt[i].p_type) == PT_DYNAMIC) {
39 dyn = addr + GET(pt[i].p_offset); 39 dyn = addr + GET_LE(pt[i].p_offset);
40 dyn_end = addr + GET(pt[i].p_offset) + 40 dyn_end = addr + GET_LE(pt[i].p_offset) +
41 GET(pt[i].p_memsz); 41 GET_LE(pt[i].p_memsz);
42 } 42 }
43 } 43 }
44 if (!found_load) 44 if (!found_load)
@@ -46,48 +46,51 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
46 data_size = (load_size + 4095) / 4096 * 4096; 46 data_size = (load_size + 4095) / 4096 * 4096;
47 47
48 /* Walk the dynamic table */ 48 /* Walk the dynamic table */
49 for (i = 0; dyn + i < dyn_end && GET(dyn[i].d_tag) != DT_NULL; i++) { 49 for (i = 0; dyn + i < dyn_end &&
50 typeof(dyn[i].d_tag) tag = GET(dyn[i].d_tag); 50 GET_LE(dyn[i].d_tag) != DT_NULL; i++) {
51 typeof(dyn[i].d_tag) tag = GET_LE(dyn[i].d_tag);
51 if (tag == DT_REL || tag == DT_RELSZ || 52 if (tag == DT_REL || tag == DT_RELSZ ||
52 tag == DT_RELENT || tag == DT_TEXTREL) 53 tag == DT_RELENT || tag == DT_TEXTREL)
53 fail("vdso image contains dynamic relocations\n"); 54 fail("vdso image contains dynamic relocations\n");
54 } 55 }
55 56
56 /* Walk the section table */ 57 /* Walk the section table */
57 secstrings_hdr = addr + GET(hdr->e_shoff) + 58 secstrings_hdr = addr + GET_LE(hdr->e_shoff) +
58 GET(hdr->e_shentsize)*GET(hdr->e_shstrndx); 59 GET_LE(hdr->e_shentsize)*GET_LE(hdr->e_shstrndx);
59 secstrings = addr + GET(secstrings_hdr->sh_offset); 60 secstrings = addr + GET_LE(secstrings_hdr->sh_offset);
60 for (i = 0; i < GET(hdr->e_shnum); i++) { 61 for (i = 0; i < GET_LE(hdr->e_shnum); i++) {
61 Elf_Shdr *sh = addr + GET(hdr->e_shoff) + 62 Elf_Shdr *sh = addr + GET_LE(hdr->e_shoff) +
62 GET(hdr->e_shentsize) * i; 63 GET_LE(hdr->e_shentsize) * i;
63 if (GET(sh->sh_type) == SHT_SYMTAB) 64 if (GET_LE(sh->sh_type) == SHT_SYMTAB)
64 symtab_hdr = sh; 65 symtab_hdr = sh;
65 66
66 if (!strcmp(secstrings + GET(sh->sh_name), ".altinstructions")) 67 if (!strcmp(secstrings + GET_LE(sh->sh_name),
68 ".altinstructions"))
67 alt_sec = sh; 69 alt_sec = sh;
68 } 70 }
69 71
70 if (!symtab_hdr) 72 if (!symtab_hdr)
71 fail("no symbol table\n"); 73 fail("no symbol table\n");
72 74
73 strtab_hdr = addr + GET(hdr->e_shoff) + 75 strtab_hdr = addr + GET_LE(hdr->e_shoff) +
74 GET(hdr->e_shentsize) * GET(symtab_hdr->sh_link); 76 GET_LE(hdr->e_shentsize) * GET_LE(symtab_hdr->sh_link);
75 77
76 /* Walk the symbol table */ 78 /* Walk the symbol table */
77 for (i = 0; i < GET(symtab_hdr->sh_size) / GET(symtab_hdr->sh_entsize); 79 for (i = 0;
80 i < GET_LE(symtab_hdr->sh_size) / GET_LE(symtab_hdr->sh_entsize);
78 i++) { 81 i++) {
79 int k; 82 int k;
80 Elf_Sym *sym = addr + GET(symtab_hdr->sh_offset) + 83 Elf_Sym *sym = addr + GET_LE(symtab_hdr->sh_offset) +
81 GET(symtab_hdr->sh_entsize) * i; 84 GET_LE(symtab_hdr->sh_entsize) * i;
82 const char *name = addr + GET(strtab_hdr->sh_offset) + 85 const char *name = addr + GET_LE(strtab_hdr->sh_offset) +
83 GET(sym->st_name); 86 GET_LE(sym->st_name);
84 for (k = 0; k < NSYMS; k++) { 87 for (k = 0; k < NSYMS; k++) {
85 if (!strcmp(name, required_syms[k])) { 88 if (!strcmp(name, required_syms[k])) {
86 if (syms[k]) { 89 if (syms[k]) {
87 fail("duplicate symbol %s\n", 90 fail("duplicate symbol %s\n",
88 required_syms[k]); 91 required_syms[k]);
89 } 92 }
90 syms[k] = GET(sym->st_value); 93 syms[k] = GET_LE(sym->st_value);
91 } 94 }
92 } 95 }
93 } 96 }
@@ -147,9 +150,9 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
147 fprintf(outfile, "\t},\n"); 150 fprintf(outfile, "\t},\n");
148 if (alt_sec) { 151 if (alt_sec) {
149 fprintf(outfile, "\t.alt = %lu,\n", 152 fprintf(outfile, "\t.alt = %lu,\n",
150 (unsigned long)GET(alt_sec->sh_offset)); 153 (unsigned long)GET_LE(alt_sec->sh_offset));
151 fprintf(outfile, "\t.alt_len = %lu,\n", 154 fprintf(outfile, "\t.alt_len = %lu,\n",
152 (unsigned long)GET(alt_sec->sh_size)); 155 (unsigned long)GET_LE(alt_sec->sh_size));
153 } 156 }
154 for (i = 0; i < NSYMS; i++) { 157 for (i = 0; i < NSYMS; i++) {
155 if (syms[i]) 158 if (syms[i])