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