Commit 15338fd765041410bc1aa0d7fe7bea7c2849fcde

Authored by bellard
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
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;