diff options
| -rw-r--r-- | arch/x86/vdso/vdso2c.c | 16 | ||||
| -rw-r--r-- | arch/x86/vdso/vdso2c.h | 65 |
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 | ||
| 62 | extern void bad_get(uint64_t); | 62 | extern 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]) |
