qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] MacOS X for Intel host support


From: Gwenole Beauchesne
Subject: [Qemu-devel] [PATCH] MacOS X for Intel host support
Date: Mon, 13 Feb 2006 11:57:16 +0100 (CET)

Hi,

I am not fully satisfied with those patches though. The dyngen-exec.h &
exec-all.h bits should be improved and depend on gcc4 patches.

TODO:
- try test-i386
- use 80-bit long doubles?

--- qemu-0.8.0/target-i386/exec.h.osx-intel-port        2005-12-19 
23:51:53.000000000 +0100
+++ qemu-0.8.0/target-i386/exec.h       2006-02-13 07:20:25.000000000 +0100
@@ -457,8 +457,6 @@ static inline void helper_fstt(CPU86_LDo
 
 #define FPUC_EM 0x3f
 
-extern const CPU86_LDouble f15rk[7];
-
 void helper_fldt_ST0_A0(void);
 void helper_fstt_ST0_A0(void);
 void fpu_raise_exception(void);
@@ -492,10 +490,6 @@ float approx_rsqrt(float a);
 float approx_rcp(float a);
 void update_fp_status(void);
 
-extern const uint8_t parity_table[256];
-extern const uint8_t rclw_table[32];
-extern const uint8_t rclb_table[32];
-
 static inline uint32_t compute_eflags(void)
 {
     return env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
--- qemu-0.8.0/target-i386/op.c.osx-intel-port  2006-02-13 01:25:58.000000000 
+0100
+++ qemu-0.8.0/target-i386/op.c 2006-02-13 07:20:25.000000000 +0100
@@ -21,6 +21,19 @@
 #define ASM_SOFTMMU
 #include "exec.h"
 
+#if defined(__APPLE__)
+/* XXX avoid indirect symbols, correct address patched at code generation 
time.  */
+static const uint8_t parity_table[256];
+static const uint8_t rclw_table[32];
+static const uint8_t rclb_table[32];
+static const CPU86_LDouble f15rk[7];
+#else
+extern const uint8_t parity_table[256];
+extern const uint8_t rclw_table[32];
+extern const uint8_t rclb_table[32];
+extern const CPU86_LDouble f15rk[7];
+#endif
+
 /* n must be a constant to be efficient */
 static inline target_long lshift(target_long x, int n)
 {
--- qemu-0.8.0/Makefile.target.osx-intel-port   2006-02-13 01:25:58.000000000 
+0100
+++ qemu-0.8.0/Makefile.target  2006-02-13 01:25:58.000000000 +0100
@@ -18,6 +18,9 @@ VPATH+=:$(SRC_PATH)/linux-user
 DEFINES+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
 endif
 CFLAGS=-Wall -O2 -g -fno-strict-aliasing
+ifeq ($(CONFIG_DARWIN),yes)
+CFLAGS+=-mdynamic-no-pic
+endif
 #CFLAGS+=-Werror
 LDFLAGS=-g
 LIBS=
@@ -156,7 +159,6 @@ OP_CFLAGS+=-fno-reorder-blocks -fno-opti
 endif
 
 ifeq ($(CONFIG_DARWIN),yes)
-OP_CFLAGS+= -mdynamic-no-pic
 LIBS+=-lmx
 endif
 
--- qemu-0.8.0/dyngen.c.osx-intel-port  2006-02-13 01:25:58.000000000 +0100
+++ qemu-0.8.0/dyngen.c 2006-02-13 01:25:58.000000000 +0100
@@ -183,6 +183,20 @@ typedef struct coff_rel {
 #include <mach-o/reloc.h>
 #include <mach-o/ppc/reloc.h>
 
+#ifdef HOST_PPC
+
+#define MACH_CPU_TYPE CPU_TYPE_POWERPC
+#define mach_check_cputype(x) ((x) == CPU_TYPE_POWERPC)
+
+#elif defined(HOST_I386)
+
+#define MACH_CPU_TYPE CPU_TYPE_I386
+#define mach_check_cputype(x) ((x) == CPU_TYPE_I386)
+
+#else
+#error unsupported CPU - please update the code
+#endif
+
 # define check_mach_header(x) (x.magic == MH_MAGIC)
 typedef int32_t host_long;
 typedef uint32_t host_ulong;
@@ -981,22 +995,23 @@ static const char * find_reloc_name_in_s
 {
     unsigned int tocindex, symindex, size;
     const char *name = 0;
+       int section_type;
     
     /* Sanity check */
     if(!( address >= sec_hdr->addr && address < (sec_hdr->addr + 
sec_hdr->size) ) )
         return (char*)0;
-               
-       if( sec_hdr->flags & S_SYMBOL_STUBS ){
+
+       section_type = sec_hdr->flags & SECTION_TYPE;
+       if( section_type == S_SYMBOL_STUBS ){
                size = sec_hdr->reserved2;
                if(size == 0)
                    error("size = 0");
-               
        }
-       else if( sec_hdr->flags & S_LAZY_SYMBOL_POINTERS ||
-                   sec_hdr->flags & S_NON_LAZY_SYMBOL_POINTERS)
+       else if( section_type == S_LAZY_SYMBOL_POINTERS ||
+                        section_type == S_NON_LAZY_SYMBOL_POINTERS)
                size = sizeof(unsigned long);
        else
-               return 0;
+               return NULL;
                
     /* Compute our index in toc */
        tocindex = (address - sec_hdr->addr)/size;
@@ -1030,8 +1045,27 @@ static const char * get_reloc_name(EXE_R
        /* init the slide value */
        *sslide = 0;
        
-       if(R_SCATTERED & rel->r_address)
-               return (char 
*)find_reloc_name_given_its_address(sca_rel->r_value);
+       if (R_SCATTERED & rel->r_address) {
+        char *name = (char 
*)find_reloc_name_given_its_address(sca_rel->r_value);
+
+        /* search it in the full symbol list, if not found */
+        if (!name) {
+            int i;
+            for (i = 0; i < nb_syms; i++) {
+                EXE_SYM *sym = &symtab[i];
+                if (sym->st_value == sca_rel->r_value) {
+                    name = get_sym_name(sym);
+                    switch (sca_rel->r_type) {
+                    case GENERIC_RELOC_VANILLA:
+                        *sslide = *(uint32_t *)(text + sca_rel->r_address) - 
sca_rel->r_value;
+                        break;
+                    }
+                    break;
+                }
+            }
+        }
+        return name;
+    }
 
        if(rel->r_extern)
        {
@@ -1063,14 +1097,21 @@ static const char * get_reloc_name(EXE_R
                        sectoffset = ( *(uint32_t *)(text + rel->r_address) & 
0x03fffffc );
                        if (sectoffset & 0x02000000) sectoffset |= 0xfc000000;
                        break;
+        case GENERIC_RELOC_VANILLA:
+            sectoffset  = *(uint32_t *)(text + rel->r_address);
+            break;
                default:
-                       error("switch(rel->type) not found");
+                       error("switch(rel->type=%d) not found", rel->r_type);
        }
 
-       if(rel->r_pcrel)
+       if(rel->r_pcrel) {
                sectoffset += rel->r_address;
-                       
-       if (rel->r_type == PPC_RELOC_BR24)
+#ifdef HOST_I386
+        sectoffset += (1 << rel->r_length);
+#endif
+    }
+
+       if (rel->r_type == PPC_RELOC_BR24 || rel->r_pcrel)
                name = (char *)find_reloc_name_in_sec_ptr((int)sectoffset, 
&section_hdr[sectnum-1]);
 
        /* search it in the full symbol list, if not found */
@@ -1122,7 +1163,7 @@ int load_object(const char *filename)
         error("bad Mach header");
     }
     
-    if (mach_hdr.cputype != CPU_TYPE_POWERPC)
+    if (!mach_check_cputype(mach_hdr.cputype))
         error("Unsupported CPU");
         
     if (mach_hdr.filetype != MH_OBJECT)
@@ -2413,6 +2454,82 @@ void gen_code(const char *name, host_ulo
         /* patch relocations */
 #if defined(HOST_I386)
             {
+#ifdef CONFIG_FORMAT_MACH
+                struct scattered_relocation_info *scarel;
+                struct relocation_info * rel;
+                               char final_sym_name[256];
+                               const char *sym_name;
+                               const char *p;
+                               int slide, sslide;
+                               int i;
+       
+                               for (i = 0, rel = relocs; i < nb_relocs; i++, 
rel++) {
+                                       unsigned int offset, length, value = 0;
+                                       unsigned int type, pcrel, isym = 0;
+                                       unsigned int usesym = 0;
+                               
+                                       if (R_SCATTERED & rel->r_address) {
+                                               scarel = (struct 
scattered_relocation_info*)rel;
+                                               offset = (unsigned 
int)scarel->r_address;
+                                               length = scarel->r_length;
+                                               pcrel = scarel->r_pcrel;
+                                               type = scarel->r_type;
+                                               value = scarel->r_value;
+                                       }
+                    else {
+                                               value = isym = rel->r_symbolnum;
+                                               usesym = (rel->r_extern);
+                                               offset = rel->r_address;
+                                               length = rel->r_length;
+                                               pcrel = rel->r_pcrel;
+                                               type = rel->r_type;
+                                       }
+                               
+                                       slide = offset - start_offset;
+               
+                                       if (!(offset >= start_offset && offset 
< start_offset + size)) 
+                                               continue;  /* not in our range 
*/
+
+                                       sym_name = get_reloc_name(rel, &sslide);
+                                       
+                                       if (usesym && symtab[isym].n_type & 
N_STAB)
+                                               continue; /* don't handle STAB 
(debug sym) */
+                                       
+                                       if (sym_name && strstart(sym_name, 
"__op_jmp", &p)) {
+                                               int n;
+                                               n = strtol(p, NULL, 10);
+                                               fprintf(outfile, "    
jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n", n, slide);
+                                               continue; /* Nothing more to do 
*/
+                                       }
+                                       
+                                       if (!sym_name) {
+                                               fprintf(outfile, "/* #warning 
relocation not handled in %s (value 0x%x, %s, offset 0x%x, length 0x%x, %s, 
type 0x%x) */\n",
+                                name, value, usesym ? "use sym" : "don't use 
sym", offset, length, pcrel ? "pcrel":"", type);
+                                               continue; /* dunno how to 
handle without final_sym_name */
+                                       }
+
+                    get_reloc_expr(final_sym_name, sizeof(final_sym_name),
+                                   sym_name);
+
+                    if (length != 2)
+                        error("unsupported %d-bit relocation", 8 * (1 << 
length));
+
+                                       switch (type) {
+                                       case GENERIC_RELOC_VANILLA:
+                        if (pcrel || strstart(sym_name,"__op_gen_label",&p)) {
+                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + 
%d) = %s - (long)(gen_code_ptr + %d) - 4;\n",
+                                    slide, final_sym_name, slide);
+                        }
+                        else {
+                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + 
%d) = (%s + %d);\n", 
+                                    slide, final_sym_name, sslide);
+                        }
+                        break;
+                    default:
+                        error("unsupported i386 relocation (%d)", type);
+                    }
+                }
+#else
                 char name[256];
                 int type;
                 int addend;
@@ -2482,6 +2599,7 @@ void gen_code(const char *name, host_ulo
 #endif
                 }
                }
+#endif
                 /* Replace the marker instructions with the actual opcodes.  */
                 for (i = 0; exit_addrs[i] != -1; i++) {
                     int op;
--- qemu-0.8.0/dyngen-exec.h.osx-intel-port     2006-02-13 01:25:58.000000000 
+0100
+++ qemu-0.8.0/dyngen-exec.h    2006-02-13 01:25:58.000000000 +0100
@@ -215,9 +215,16 @@ extern int __op_jmp0, __op_jmp1, __op_jm
 #define EXIT_TB() asm volatile ("hlt")
 /* Dyngen will replace cli with 0x9e (jmp). 
    We generate the offset manually.  */
+#if defined(__APPLE__)
+/* XXX Different relocations are generated for MacOS X for Intel
+   (please as from cctools).  */
+#define GOTO_LABEL_PARAM(n) \
+  asm volatile ("cli;.long " ASM_NAME(__op_gen_label) #n)
+#else
 #define GOTO_LABEL_PARAM(n) \
   asm volatile ("cli;.long " ASM_NAME(__op_gen_label) #n " - 1f;1:")
 #endif
+#endif
 #ifdef __x86_64__
 /* The same as i386.  */
 #define EXIT_TB() asm volatile ("hlt")
--- qemu-0.8.0/exec-all.h.osx-intel-port        2006-02-13 01:25:58.000000000 
+0100
+++ qemu-0.8.0/exec-all.h       2006-02-13 01:25:58.000000000 +0100
@@ -321,15 +321,29 @@ do {\
 
 /* we patch the jump instruction directly.  Use sti in place of the actual
    jmp instruction so that dyngen can patch in the correct result.  */
+#if defined(__APPLE__)
+/* XXX Different relocations are generated for MacOS X for Intel
+   (please as from cctools).  */
 #define GOTO_TB(opname, tbparam, n)\
 do {\
-    asm volatile (".section .data\n"\
+    asm volatile (ASM_DATA_SECTION\
+                 ASM_OP_LABEL_NAME(n, opname) ":\n"\
+                 ".long 1f\n"\
+                 ASM_PREVIOUS_SECTION \
+                  "sti;.long " ASM_NAME(__op_jmp) #n "\n"\
+                 "1:\n");\
+} while (0)
+#else
+#define GOTO_TB(opname, tbparam, n)\
+do {\
+    asm volatile (ASM_DATA_SECTION\
                  ASM_OP_LABEL_NAME(n, opname) ":\n"\
                  ".long 1f\n"\
                  ASM_PREVIOUS_SECTION \
                   "sti;.long " ASM_NAME(__op_jmp) #n " - 1f\n"\
                  "1:\n");\
 } while (0)
+#endif
 
 #else
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]