diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-11-26 11:41:16 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-11-26 11:41:16 +0000 |
commit | 15338fd765041410bc1aa0d7fe7bea7c2849fcde (patch) | |
tree | a74ac917ad5912a0e148a0173dfade3d0c1baa5b | |
parent | 79639d423f779e65f24d0fcc05b14d6c45b4a894 (diff) | |
download | hqemu-15338fd765041410bc1aa0d7fe7bea7c2849fcde.zip hqemu-15338fd765041410bc1aa0d7fe7bea7c2849fcde.tar.gz |
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
-rw-r--r-- | linux-user/elfload.c | 53 | ||||
-rw-r--r-- | linux-user/main.c | 3 |
2 files changed, 46 insertions, 10 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 2ae1e53..eda6e9b 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -25,6 +25,26 @@ #ifdef TARGET_I386 +#define ELF_PLATFORM get_elf_platform() + +static const char *get_elf_platform(void) +{ + static char elf_platform[] = "i386"; + int family = (global_env->cpuid_version >> 8) & 0xff; + if (family > 6) + family = 6; + if (family >= 3) + elf_platform[1] = '0' + family; + return elf_platform; +} + +#define ELF_HWCAP get_elf_hwcap() + +static uint32_t get_elf_hwcap(void) +{ + return global_env->cpuid_features; +} + #define ELF_START_MMAP 0x80000000 /* @@ -91,7 +111,6 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE 4096 -#define DLINFO_ARCH_ITEMS 1 enum { ARM_HWCAP_ARM_SWP = 1 << 0, @@ -104,15 +123,10 @@ enum ARM_HWCAP_ARM_EDSP = 1 << 7, }; -#define ARM_HWCAPS (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF \ +#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF \ | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \ | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP) -#define ARCH_DLINFO \ -do { \ - NEW_AUX_ENT(AT_HWCAP, ARM_HWCAPS); \ -} while (0) - #endif #ifdef TARGET_SPARC @@ -233,6 +247,14 @@ static inline void init_thread(struct target_pt_regs *_regs, struct image_info * #endif +#ifndef ELF_PLATFORM +#define ELF_PLATFORM (NULL) +#endif + +#ifndef ELF_HWCAP +#define ELF_HWCAP 0 +#endif + #include "elf.h" /* @@ -314,7 +336,7 @@ struct exec #define INTERPRETER_AOUT 1 #define INTERPRETER_ELF 2 -#define DLINFO_ITEMS 11 +#define DLINFO_ITEMS 12 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) { @@ -646,14 +668,26 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc, { target_ulong *argv, *envp; target_ulong *sp, *csp; + target_ulong *u_platform; + const char *k_platform; int v; /* * Force 16 byte _final_ alignment here for generality. */ sp = (unsigned int *) (~15UL & (unsigned long) p); + u_platform = NULL; + k_platform = ELF_PLATFORM; + if (k_platform) { + size_t len = strlen(k_platform) + 1; + sp -= (len + sizeof(target_ulong) - 1) / sizeof(target_ulong); + u_platform = (target_ulong *)sp; + __copy_to_user(u_platform, k_platform, len); + } csp = sp; csp -= (DLINFO_ITEMS + 1) * 2; + if (k_platform) + csp -= 2; #ifdef DLINFO_ARCH_ITEMS csp -= DLINFO_ARCH_ITEMS*2; #endif @@ -681,6 +715,9 @@ static unsigned int * create_elf_tables(char *p, int argc, int envc, NEW_AUX_ENT(AT_EUID, (target_ulong) geteuid()); NEW_AUX_ENT(AT_GID, (target_ulong) getgid()); NEW_AUX_ENT(AT_EGID, (target_ulong) getegid()); + NEW_AUX_ENT(AT_HWCAP, (target_ulong) ELF_HWCAP); + if (k_platform) + NEW_AUX_ENT(AT_PLATFORM, (target_ulong) u_platform); #ifdef ARCH_DLINFO /* * ARCH_DLINFO must come last so platform specific code can enforce diff --git a/linux-user/main.c b/linux-user/main.c index 1b747d8..4b7fd7c 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -1098,6 +1098,7 @@ int main(int argc, char **argv) /* NOTE: we need to init the CPU at this stage to get qemu_host_page_size */ env = cpu_init(); + global_env = env; if (elf_exec(filename, argv+optind, environ, regs, info) != 0) { printf("Error loading %s\n", filename); @@ -1120,8 +1121,6 @@ int main(int argc, char **argv) syscall_init(); signal_init(); - global_env = env; - /* build Task State */ memset(ts, 0, sizeof(TaskState)); env->opaque = ts; |