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; |