]> git.proxmox.com Git - mirror_qemu.git/commitdiff
added AT_PLATFORM and AT_HWCAP for x86 (initial patch by Gwenole Beauchesne)
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 26 Nov 2005 11:41:16 +0000 (11:41 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 26 Nov 2005 11:41:16 +0000 (11:41 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1665 c046a42c-6fe2-441c-8c8c-71466251a162

linux-user/elfload.c
linux-user/main.c

index 2ae1e5324a0f65a1ad6b1746615b1a60edba38d7..eda6e9ba23205e2169ac99aa338b654f50c5b2bc 100644 (file)
 
 #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
index 1b747d87386867eba92a9bb28d7053055a01d44f..4b7fd7ca8c0ce1fcf85d44cf25c3bc0726f4e3a9 100644 (file)
@@ -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;