Commit 15338fd765041410bc1aa0d7fe7bea7c2849fcde
1 parent
79639d42
added AT_PLATFORM and AT_HWCAP for x86 (initial patch by Gwenole Beauchesne)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1665 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
46 additions
and
10 deletions
linux-user/elfload.c
... | ... | @@ -25,6 +25,26 @@ |
25 | 25 | |
26 | 26 | #ifdef TARGET_I386 |
27 | 27 | |
28 | +#define ELF_PLATFORM get_elf_platform() | |
29 | + | |
30 | +static const char *get_elf_platform(void) | |
31 | +{ | |
32 | + static char elf_platform[] = "i386"; | |
33 | + int family = (global_env->cpuid_version >> 8) & 0xff; | |
34 | + if (family > 6) | |
35 | + family = 6; | |
36 | + if (family >= 3) | |
37 | + elf_platform[1] = '0' + family; | |
38 | + return elf_platform; | |
39 | +} | |
40 | + | |
41 | +#define ELF_HWCAP get_elf_hwcap() | |
42 | + | |
43 | +static uint32_t get_elf_hwcap(void) | |
44 | +{ | |
45 | + return global_env->cpuid_features; | |
46 | +} | |
47 | + | |
28 | 48 | #define ELF_START_MMAP 0x80000000 |
29 | 49 | |
30 | 50 | /* |
... | ... | @@ -91,7 +111,6 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i |
91 | 111 | #define USE_ELF_CORE_DUMP |
92 | 112 | #define ELF_EXEC_PAGESIZE 4096 |
93 | 113 | |
94 | -#define DLINFO_ARCH_ITEMS 1 | |
95 | 114 | enum |
96 | 115 | { |
97 | 116 | ARM_HWCAP_ARM_SWP = 1 << 0, |
... | ... | @@ -104,15 +123,10 @@ enum |
104 | 123 | ARM_HWCAP_ARM_EDSP = 1 << 7, |
105 | 124 | }; |
106 | 125 | |
107 | -#define ARM_HWCAPS (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF \ | |
126 | +#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF \ | |
108 | 127 | | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \ |
109 | 128 | | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP) |
110 | 129 | |
111 | -#define ARCH_DLINFO \ | |
112 | -do { \ | |
113 | - NEW_AUX_ENT(AT_HWCAP, ARM_HWCAPS); \ | |
114 | -} while (0) | |
115 | - | |
116 | 130 | #endif |
117 | 131 | |
118 | 132 | #ifdef TARGET_SPARC |
... | ... | @@ -233,6 +247,14 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info * |
233 | 247 | |
234 | 248 | #endif |
235 | 249 | |
250 | +#ifndef ELF_PLATFORM | |
251 | +#define ELF_PLATFORM (NULL) | |
252 | +#endif | |
253 | + | |
254 | +#ifndef ELF_HWCAP | |
255 | +#define ELF_HWCAP 0 | |
256 | +#endif | |
257 | + | |
236 | 258 | #include "elf.h" |
237 | 259 | |
238 | 260 | /* |
... | ... | @@ -314,7 +336,7 @@ struct exec |
314 | 336 | #define INTERPRETER_AOUT 1 |
315 | 337 | #define INTERPRETER_ELF 2 |
316 | 338 | |
317 | -#define DLINFO_ITEMS 11 | |
339 | +#define DLINFO_ITEMS 12 | |
318 | 340 | |
319 | 341 | static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) |
320 | 342 | { |
... | ... | @@ -646,14 +668,26 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc, |
646 | 668 | { |
647 | 669 | target_ulong *argv, *envp; |
648 | 670 | target_ulong *sp, *csp; |
671 | + target_ulong *u_platform; | |
672 | + const char *k_platform; | |
649 | 673 | int v; |
650 | 674 | |
651 | 675 | /* |
652 | 676 | * Force 16 byte _final_ alignment here for generality. |
653 | 677 | */ |
654 | 678 | sp = (unsigned int *) (~15UL & (unsigned long) p); |
679 | + u_platform = NULL; | |
680 | + k_platform = ELF_PLATFORM; | |
681 | + if (k_platform) { | |
682 | + size_t len = strlen(k_platform) + 1; | |
683 | + sp -= (len + sizeof(target_ulong) - 1) / sizeof(target_ulong); | |
684 | + u_platform = (target_ulong *)sp; | |
685 | + __copy_to_user(u_platform, k_platform, len); | |
686 | + } | |
655 | 687 | csp = sp; |
656 | 688 | csp -= (DLINFO_ITEMS + 1) * 2; |
689 | + if (k_platform) | |
690 | + csp -= 2; | |
657 | 691 | #ifdef DLINFO_ARCH_ITEMS |
658 | 692 | csp -= DLINFO_ARCH_ITEMS*2; |
659 | 693 | #endif |
... | ... | @@ -681,6 +715,9 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc, |
681 | 715 | NEW_AUX_ENT(AT_EUID, (target_ulong) geteuid()); |
682 | 716 | NEW_AUX_ENT(AT_GID, (target_ulong) getgid()); |
683 | 717 | NEW_AUX_ENT(AT_EGID, (target_ulong) getegid()); |
718 | + NEW_AUX_ENT(AT_HWCAP, (target_ulong) ELF_HWCAP); | |
719 | + if (k_platform) | |
720 | + NEW_AUX_ENT(AT_PLATFORM, (target_ulong) u_platform); | |
684 | 721 | #ifdef ARCH_DLINFO |
685 | 722 | /* |
686 | 723 | * ARCH_DLINFO must come last so platform specific code can enforce | ... | ... |
linux-user/main.c
... | ... | @@ -1098,6 +1098,7 @@ int main(int argc, char **argv) |
1098 | 1098 | /* NOTE: we need to init the CPU at this stage to get |
1099 | 1099 | qemu_host_page_size */ |
1100 | 1100 | env = cpu_init(); |
1101 | + global_env = env; | |
1101 | 1102 | |
1102 | 1103 | if (elf_exec(filename, argv+optind, environ, regs, info) != 0) { |
1103 | 1104 | printf("Error loading %s\n", filename); |
... | ... | @@ -1120,8 +1121,6 @@ int main(int argc, char **argv) |
1120 | 1121 | syscall_init(); |
1121 | 1122 | signal_init(); |
1122 | 1123 | |
1123 | - global_env = env; | |
1124 | - | |
1125 | 1124 | /* build Task State */ |
1126 | 1125 | memset(ts, 0, sizeof(TaskState)); |
1127 | 1126 | env->opaque = ts; | ... | ... |