x49gp/qemu/patches/qemu-0.9.0-osx-intel-port.patch

329 lines
11 KiB
Diff

2007-02-01 Mike Kronenberg <mike.kronenberg@kronenberg.org>
* Fix for QEMU 0.9.0.
2006-02-12 Gwenole Beauchesne <gb.public@free.fr>
* Port to MacOS X for Intel.
TODO:
- try test-i386
- use 80-bit long double?
--- 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 @@ CPPFLAGS+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ARCH)
endif
BASE_CFLAGS=
BASE_LDFLAGS=
+ifeq ($(CONFIG_DARWIN),yes)
+CFLAGS+=-mdynamic-no-pic
+endif
#CFLAGS+=-Werror
LDFLAGS=-g
LIBS=
--- 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