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,6 +25,26 @@ | ||
25 | 25 | ||
26 | #ifdef TARGET_I386 | 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 | #define ELF_START_MMAP 0x80000000 | 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,7 +111,6 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i | ||
91 | #define USE_ELF_CORE_DUMP | 111 | #define USE_ELF_CORE_DUMP |
92 | #define ELF_EXEC_PAGESIZE 4096 | 112 | #define ELF_EXEC_PAGESIZE 4096 |
93 | 113 | ||
94 | -#define DLINFO_ARCH_ITEMS 1 | ||
95 | enum | 114 | enum |
96 | { | 115 | { |
97 | ARM_HWCAP_ARM_SWP = 1 << 0, | 116 | ARM_HWCAP_ARM_SWP = 1 << 0, |
@@ -104,15 +123,10 @@ enum | @@ -104,15 +123,10 @@ enum | ||
104 | ARM_HWCAP_ARM_EDSP = 1 << 7, | 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 | | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \ | 127 | | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \ |
109 | | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP) | 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 | #endif | 130 | #endif |
117 | 131 | ||
118 | #ifdef TARGET_SPARC | 132 | #ifdef TARGET_SPARC |
@@ -233,6 +247,14 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info * | @@ -233,6 +247,14 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info * | ||
233 | 247 | ||
234 | #endif | 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 | #include "elf.h" | 258 | #include "elf.h" |
237 | 259 | ||
238 | /* | 260 | /* |
@@ -314,7 +336,7 @@ struct exec | @@ -314,7 +336,7 @@ struct exec | ||
314 | #define INTERPRETER_AOUT 1 | 336 | #define INTERPRETER_AOUT 1 |
315 | #define INTERPRETER_ELF 2 | 337 | #define INTERPRETER_ELF 2 |
316 | 338 | ||
317 | -#define DLINFO_ITEMS 11 | 339 | +#define DLINFO_ITEMS 12 |
318 | 340 | ||
319 | static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) | 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,14 +668,26 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc, | ||
646 | { | 668 | { |
647 | target_ulong *argv, *envp; | 669 | target_ulong *argv, *envp; |
648 | target_ulong *sp, *csp; | 670 | target_ulong *sp, *csp; |
671 | + target_ulong *u_platform; | ||
672 | + const char *k_platform; | ||
649 | int v; | 673 | int v; |
650 | 674 | ||
651 | /* | 675 | /* |
652 | * Force 16 byte _final_ alignment here for generality. | 676 | * Force 16 byte _final_ alignment here for generality. |
653 | */ | 677 | */ |
654 | sp = (unsigned int *) (~15UL & (unsigned long) p); | 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 | csp = sp; | 687 | csp = sp; |
656 | csp -= (DLINFO_ITEMS + 1) * 2; | 688 | csp -= (DLINFO_ITEMS + 1) * 2; |
689 | + if (k_platform) | ||
690 | + csp -= 2; | ||
657 | #ifdef DLINFO_ARCH_ITEMS | 691 | #ifdef DLINFO_ARCH_ITEMS |
658 | csp -= DLINFO_ARCH_ITEMS*2; | 692 | csp -= DLINFO_ARCH_ITEMS*2; |
659 | #endif | 693 | #endif |
@@ -681,6 +715,9 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc, | @@ -681,6 +715,9 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc, | ||
681 | NEW_AUX_ENT(AT_EUID, (target_ulong) geteuid()); | 715 | NEW_AUX_ENT(AT_EUID, (target_ulong) geteuid()); |
682 | NEW_AUX_ENT(AT_GID, (target_ulong) getgid()); | 716 | NEW_AUX_ENT(AT_GID, (target_ulong) getgid()); |
683 | NEW_AUX_ENT(AT_EGID, (target_ulong) getegid()); | 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 | #ifdef ARCH_DLINFO | 721 | #ifdef ARCH_DLINFO |
685 | /* | 722 | /* |
686 | * ARCH_DLINFO must come last so platform specific code can enforce | 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,6 +1098,7 @@ int main(int argc, char **argv) | ||
1098 | /* NOTE: we need to init the CPU at this stage to get | 1098 | /* NOTE: we need to init the CPU at this stage to get |
1099 | qemu_host_page_size */ | 1099 | qemu_host_page_size */ |
1100 | env = cpu_init(); | 1100 | env = cpu_init(); |
1101 | + global_env = env; | ||
1101 | 1102 | ||
1102 | if (elf_exec(filename, argv+optind, environ, regs, info) != 0) { | 1103 | if (elf_exec(filename, argv+optind, environ, regs, info) != 0) { |
1103 | printf("Error loading %s\n", filename); | 1104 | printf("Error loading %s\n", filename); |
@@ -1120,8 +1121,6 @@ int main(int argc, char **argv) | @@ -1120,8 +1121,6 @@ int main(int argc, char **argv) | ||
1120 | syscall_init(); | 1121 | syscall_init(); |
1121 | signal_init(); | 1122 | signal_init(); |
1122 | 1123 | ||
1123 | - global_env = env; | ||
1124 | - | ||
1125 | /* build Task State */ | 1124 | /* build Task State */ |
1126 | memset(ts, 0, sizeof(TaskState)); | 1125 | memset(ts, 0, sizeof(TaskState)); |
1127 | env->opaque = ts; | 1126 | env->opaque = ts; |