aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/vdso
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@amacapital.net>2014-05-30 11:48:49 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2014-05-30 19:58:43 -0400
commitadd4eed0a2abea3951206f504330ee5daf8c178a (patch)
tree887492cf9d0f28135e9c353a5ceafe6d3e633247 /arch/x86/vdso
parent011561837dad082a92c0537db2d134e66419c6ad (diff)
x86/vdso, build: Fix cross-compilation from big-endian architectures
This adds a macro GET(x) to convert x from big-endian to little-endian. Hopefully I put it everywhere it needs to go and got all the cases needed for everyone's linux/elf.h. Signed-off-by: Andy Lutomirski <luto@amacapital.net> Link: http://lkml.kernel.org/r/2cf258df123cb24bad63c274c8563c050547d99d.1401464755.git.luto@amacapital.net Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/vdso')
-rw-r--r--arch/x86/vdso/vdso2c.c15
-rw-r--r--arch/x86/vdso/vdso2c.h63
2 files changed, 50 insertions, 28 deletions
diff --git a/arch/x86/vdso/vdso2c.c b/arch/x86/vdso/vdso2c.c
index fe8bfbf62612..de19ced6c87d 100644
--- a/arch/x86/vdso/vdso2c.c
+++ b/arch/x86/vdso/vdso2c.c
@@ -51,6 +51,21 @@ static void fail(const char *format, ...)
51 va_end(ap); 51 va_end(ap);
52} 52}
53 53
54/*
55 * Evil macros to do a little-endian read.
56 */
57#define __GET_TYPE(x, type, bits, ifnot) \
58 __builtin_choose_expr( \
59 __builtin_types_compatible_p(typeof(x), type), \
60 le##bits##toh((x)), ifnot)
61
62extern void bad_get(uint64_t);
63
64#define GET(x) \
65 __GET_TYPE((x), __u32, 32, __GET_TYPE((x), __u64, 64, \
66 __GET_TYPE((x), __s32, 32, __GET_TYPE((x), __s64, 64, \
67 __GET_TYPE((x), __u16, 16, bad_get(x))))))
68
54#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0])) 69#define NSYMS (sizeof(required_syms) / sizeof(required_syms[0]))
55 70
56#define BITS 64 71#define BITS 64
diff --git a/arch/x86/vdso/vdso2c.h b/arch/x86/vdso/vdso2c.h
index 26a7c1fa7452..f0475dad2286 100644
--- a/arch/x86/vdso/vdso2c.h
+++ b/arch/x86/vdso/vdso2c.h
@@ -18,25 +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 + hdr->e_phoff); 21 Elf_Phdr *pt = (Elf_Phdr *)(addr + GET(hdr->e_phoff));
22 22
23 /* Walk the segment table. */ 23 /* Walk the segment table. */
24 for (i = 0; i < hdr->e_phnum; i++) { 24 for (i = 0; i < GET(hdr->e_phnum); i++) {
25 if (pt[i].p_type == PT_LOAD) { 25 if (GET(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 (pt[i].p_offset != 0 || pt[i].p_vaddr != 0) 29 if (GET(pt[i].p_offset) != 0 ||
30 GET(pt[i].p_vaddr) != 0)
30 fail("PT_LOAD in wrong place\n"); 31 fail("PT_LOAD in wrong place\n");
31 32
32 if (pt[i].p_memsz != pt[i].p_filesz) 33 if (GET(pt[i].p_memsz) != GET(pt[i].p_filesz))
33 fail("cannot handle memsz != filesz\n"); 34 fail("cannot handle memsz != filesz\n");
34 35
35 load_size = pt[i].p_memsz; 36 load_size = GET(pt[i].p_memsz);
36 found_load = 1; 37 found_load = 1;
37 } else if (pt[i].p_type == PT_DYNAMIC) { 38 } else if (GET(pt[i].p_type) == PT_DYNAMIC) {
38 dyn = addr + pt[i].p_offset; 39 dyn = addr + GET(pt[i].p_offset);
39 dyn_end = addr + pt[i].p_offset + pt[i].p_memsz; 40 dyn_end = addr + GET(pt[i].p_offset) +
41 GET(pt[i].p_memsz);
40 } 42 }
41 } 43 }
42 if (!found_load) 44 if (!found_load)
@@ -44,43 +46,48 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
44 data_size = (load_size + 4095) / 4096 * 4096; 46 data_size = (load_size + 4095) / 4096 * 4096;
45 47
46 /* Walk the dynamic table */ 48 /* Walk the dynamic table */
47 for (i = 0; dyn + i < dyn_end && dyn[i].d_tag != DT_NULL; i++) { 49 for (i = 0; dyn + i < dyn_end && GET(dyn[i].d_tag) != DT_NULL; i++) {
48 if (dyn[i].d_tag == DT_REL || dyn[i].d_tag == DT_RELSZ || 50 typeof(dyn[i].d_tag) tag = GET(dyn[i].d_tag);
49 dyn[i].d_tag == DT_RELENT || dyn[i].d_tag == DT_TEXTREL) 51 if (tag == DT_REL || tag == DT_RELSZ ||
52 tag == DT_RELENT || tag == DT_TEXTREL)
50 fail("vdso image contains dynamic relocations\n"); 53 fail("vdso image contains dynamic relocations\n");
51 } 54 }
52 55
53 /* Walk the section table */ 56 /* Walk the section table */
54 secstrings_hdr = addr + hdr->e_shoff + hdr->e_shentsize*hdr->e_shstrndx; 57 secstrings_hdr = addr + GET(hdr->e_shoff) +
55 secstrings = addr + secstrings_hdr->sh_offset; 58 GET(hdr->e_shentsize)*GET(hdr->e_shstrndx);
56 for (i = 0; i < hdr->e_shnum; i++) { 59 secstrings = addr + GET(secstrings_hdr->sh_offset);
57 Elf_Shdr *sh = addr + hdr->e_shoff + hdr->e_shentsize * i; 60 for (i = 0; i < GET(hdr->e_shnum); i++) {
58 if (sh->sh_type == SHT_SYMTAB) 61 Elf_Shdr *sh = addr + GET(hdr->e_shoff) +
62 GET(hdr->e_shentsize) * i;
63 if (GET(sh->sh_type) == SHT_SYMTAB)
59 symtab_hdr = sh; 64 symtab_hdr = sh;
60 65
61 if (!strcmp(secstrings + sh->sh_name, ".altinstructions")) 66 if (!strcmp(secstrings + GET(sh->sh_name), ".altinstructions"))
62 alt_sec = sh; 67 alt_sec = sh;
63 } 68 }
64 69
65 if (!symtab_hdr) 70 if (!symtab_hdr)
66 fail("no symbol table\n"); 71 fail("no symbol table\n");
67 72
68 strtab_hdr = addr + hdr->e_shoff + 73 strtab_hdr = addr + GET(hdr->e_shoff) +
69 hdr->e_shentsize * symtab_hdr->sh_link; 74 GET(hdr->e_shentsize) * GET(symtab_hdr->sh_link);
70 75
71 /* Walk the symbol table */ 76 /* Walk the symbol table */
72 for (i = 0; i < symtab_hdr->sh_size / symtab_hdr->sh_entsize; i++) { 77 for (i = 0; i < GET(symtab_hdr->sh_size) / GET(symtab_hdr->sh_entsize);
78 i++) {
73 int k; 79 int k;
74 Elf_Sym *sym = addr + symtab_hdr->sh_offset + 80 Elf_Sym *sym = addr + GET(symtab_hdr->sh_offset) +
75 symtab_hdr->sh_entsize * i; 81 GET(symtab_hdr->sh_entsize) * i;
76 const char *name = addr + strtab_hdr->sh_offset + sym->st_name; 82 const char *name = addr + GET(strtab_hdr->sh_offset) +
83 GET(sym->st_name);
77 for (k = 0; k < NSYMS; k++) { 84 for (k = 0; k < NSYMS; k++) {
78 if (!strcmp(name, required_syms[k])) { 85 if (!strcmp(name, required_syms[k])) {
79 if (syms[k]) { 86 if (syms[k]) {
80 fail("duplicate symbol %s\n", 87 fail("duplicate symbol %s\n",
81 required_syms[k]); 88 required_syms[k]);
82 } 89 }
83 syms[k] = sym->st_value; 90 syms[k] = GET(sym->st_value);
84 } 91 }
85 } 92 }
86 } 93 }
@@ -106,7 +113,7 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
106 hdr->e_shoff = 0; 113 hdr->e_shoff = 0;
107 hdr->e_shentsize = 0; 114 hdr->e_shentsize = 0;
108 hdr->e_shnum = 0; 115 hdr->e_shnum = 0;
109 hdr->e_shstrndx = SHN_UNDEF; 116 hdr->e_shstrndx = htole16(SHN_UNDEF);
110 117
111 if (!name) { 118 if (!name) {
112 fwrite(addr, load_size, 1, outfile); 119 fwrite(addr, load_size, 1, outfile);
@@ -140,9 +147,9 @@ static void GOFUNC(void *addr, size_t len, FILE *outfile, const char *name)
140 fprintf(outfile, "\t},\n"); 147 fprintf(outfile, "\t},\n");
141 if (alt_sec) { 148 if (alt_sec) {
142 fprintf(outfile, "\t.alt = %lu,\n", 149 fprintf(outfile, "\t.alt = %lu,\n",
143 (unsigned long)alt_sec->sh_offset); 150 (unsigned long)GET(alt_sec->sh_offset));
144 fprintf(outfile, "\t.alt_len = %lu,\n", 151 fprintf(outfile, "\t.alt_len = %lu,\n",
145 (unsigned long)alt_sec->sh_size); 152 (unsigned long)GET(alt_sec->sh_size));
146 } 153 }
147 for (i = 0; i < NSYMS; i++) { 154 for (i = 0; i < NSYMS; i++) {
148 if (syms[i]) 155 if (syms[i])