Index: qemu-0.9.1-aix/audio/audio.c =================================================================== --- qemu-0.9.1-aix.orig/audio/audio.c 2008-04-09 20:25:14.000000000 +0200 +++ qemu-0.9.1-aix/audio/audio.c 2008-04-09 20:25:40.-29291656 +0200 @@ -74,7 +74,7 @@ struct fixed_settings fixed_out; struct fixed_settings fixed_in; union { - int hz; + int hertz; int64_t ticks; } period; int plive; @@ -1533,7 +1533,7 @@ "Number of voices for ADC", NULL, 0}, /* Misc */ - {"TIMER_PERIOD", AUD_OPT_INT, &conf.period.hz, + {"TIMER_PERIOD", AUD_OPT_INT, &conf.period.hertz, "Timer period in HZ (0 - use lowest possible)", NULL, 0}, {"PLIVE", AUD_OPT_BOOL, &conf.plive, @@ -1794,16 +1794,16 @@ if (done) { VMChangeStateEntry *e; - if (conf.period.hz <= 0) { - if (conf.period.hz < 0) { + if (conf.period.hertz <= 0) { + if (conf.period.hertz < 0) { dolog ("warning: Timer period is negative - %d " "treating as zero\n", - conf.period.hz); + conf.period.hertz); } conf.period.ticks = 1; } else { - conf.period.ticks = ticks_per_sec / conf.period.hz; + conf.period.ticks = ticks_per_sec / conf.period.hertz; } e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s); Index: qemu-0.9.1-aix/configure =================================================================== --- qemu-0.9.1-aix.orig/configure 2008-04-09 20:25:14.000000000 +0200 +++ qemu-0.9.1-aix/configure 2008-04-09 20:25:40.-93491728 +0200 @@ -187,6 +187,12 @@ oss=yes fi ;; +AIX) + cpu="powerpc" + make="gmake" + check_gcc="no" + aix="yes" +;; *) oss="yes" linux="yes" @@ -868,6 +874,10 @@ echo "CONFIG_DARWIN=yes" >> $config_mak echo "#define CONFIG_DARWIN 1" >> $config_h fi +if test "$aix" = "yes" ; then + echo "CONFIG_AIX=yes" >> $config_mak + echo "#define CONFIG_AIX 1" >> $config_h +fi if test "$solaris" = "yes" ; then echo "CONFIG_SOLARIS=yes" >> $config_mak echo "#define HOST_SOLARIS $solarisrev" >> $config_h Index: qemu-0.9.1-aix/exec-all.h =================================================================== --- qemu-0.9.1-aix.orig/exec-all.h 2008-04-09 20:24:36.000000000 +0200 +++ qemu-0.9.1-aix/exec-all.h 2008-04-09 20:25:40.-1568183208 +0200 @@ -286,6 +286,9 @@ #elif defined(__APPLE__) #define ASM_DATA_SECTION ".data\n" #define ASM_PREVIOUS_SECTION ".text\n" +#elif defined(_AIX) +#define ASM_DATA_SECTION ".csect .data[RW],3\n" +#define ASM_PREVIOUS_SECTION ".csect .text[PR]\n" #else #define ASM_DATA_SECTION ".section \".data\"\n" #define ASM_PREVIOUS_SECTION ".previous\n" @@ -295,7 +298,14 @@ ASM_NAME(__op_label) #n "." ASM_NAME(opname) #if defined(__powerpc__) - +#if defined(_AIX) +#define GOTO_TB(opname, tbparam, n)\ +do {\ + asm volatile ("\tb " ASM_NAME(.__op_jmp) #n "\n"\ + "\t.globl ." ASM_OP_LABEL_NAME(n, opname) "\n"\ + "." ASM_OP_LABEL_NAME(n, opname) ":\n");\ +} while (0) +#else /* we patch the jump instruction directly */ #define GOTO_TB(opname, tbparam, n)\ do {\ @@ -306,6 +316,7 @@ "b " ASM_NAME(__op_jmp) #n "\n"\ "1:\n");\ } while (0) +#endif #elif defined(__i386__) && defined(USE_DIRECT_JUMP) @@ -345,12 +356,11 @@ { int ret; __asm__ __volatile__ ( - "0: lwarx %0,0,%1\n" + " lwarx %0,0,%1\n" " xor. %0,%3,%0\n" - " bne 1f\n" + " bne $ + 12\n" " stwcx. %2,0,%1\n" - " bne- 0b\n" - "1: " + " bne- $ - 16\n" : "=&r" (ret) : "r" (p), "r" (1), "r" (0) : "cr0", "memory"); Index: qemu-0.9.1-aix/fpu/softfloat.h =================================================================== --- qemu-0.9.1-aix.orig/fpu/softfloat.h 2008-04-09 20:24:36.000000000 +0200 +++ qemu-0.9.1-aix/fpu/softfloat.h 2008-04-09 20:25:40.-1633627280 +0200 @@ -51,7 +51,7 @@ typedef uint8_t uint8; typedef int8_t int8; typedef int uint16; -typedef int int16; +typedef int16_t int16; typedef unsigned int uint32; typedef signed int int32; typedef uint64_t uint64; Index: qemu-0.9.1-aix/vl.c =================================================================== --- qemu-0.9.1-aix.orig/vl.c 2008-04-09 20:25:15.000000000 +0200 +++ qemu-0.9.1-aix/vl.c 2008-04-09 20:25:40.-1697571352 +0200 @@ -67,7 +67,7 @@ #elif defined (__GLIBC__) && defined (__FreeBSD_kernel__) #include #else -#ifndef __sun__ +#if !defined(__sun__) && !defined(_AIX) #include #include #include @@ -83,9 +83,11 @@ #include #else #include +#if !defined(_AIX) #include #include #include +#endif #include #include #include @@ -3886,7 +3888,7 @@ #endif /* CONFIG_SLIRP */ -#if !defined(_WIN32) +#if !defined(_WIN32) && !defined(_AIX) typedef struct TAPState { VLANClientState *vc; @@ -4770,7 +4772,7 @@ ret = net_slirp_init(vlan); } else #endif -#ifdef _WIN32 +#if defined(_WIN32) if (!strcmp(device, "tap")) { char ifname[64]; if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) { @@ -4780,6 +4782,7 @@ vlan->nb_host_devs++; ret = tap_win32_init(vlan, ifname); } else +#elif defined(_AIX) #else if (!strcmp(device, "tap")) { char ifname[64]; @@ -9056,7 +9059,7 @@ main_loop(); quit_timers(); -#if !defined(_WIN32) +#if !defined(_WIN32) && !defined(_AIX) /* close network clients */ for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) { VLANClientState *vc; Index: qemu-0.9.1-aix/dyngen.c =================================================================== --- qemu-0.9.1-aix.orig/dyngen.c 2008-04-09 20:24:36.000000000 +0200 +++ qemu-0.9.1-aix/dyngen.c 2008-04-09 20:25:40.-1762259424 +0200 @@ -38,6 +38,8 @@ #define CONFIG_FORMAT_COFF #elif defined(CONFIG_DARWIN) #define CONFIG_FORMAT_MACH +#elif defined(CONFIG_AIX) +#define CONFIG_FORMAT_XCOFF #else #define CONFIG_FORMAT_ELF #endif @@ -219,6 +221,36 @@ #endif /* CONFIG_FORMAT_MACH */ +#ifdef CONFIG_FORMAT_XCOFF + +typedef int32_t host_long; +typedef uint32_t host_ulong; + +#include +#include + +#define FILENAMELEN 256 + +typedef struct xcoff_sym { + struct syment *st_syment; + char st_name[FILENAMELEN]; + uint32_t st_value; + int st_size; + uint8_t st_type; + uint8_t st_shndx; +} coff_Sym; + +typedef struct xcoff_rel { + struct reloc *xcoff_reloc; + int xcoff_offset; + int xcoff_size; + int xcoff_type; +} xcoff_Rel; + +#define EXE_RELOC struct xcoff_rel +#define EXE_SYM struct xcoff_sym +#endif /* CONFIG_FORMAT_XCOFF */ + #include "bswap.h" enum { @@ -228,7 +260,12 @@ }; /* all dynamically generated functions begin with this code */ + +#if defined(CONFIG_FORMAT_XCOFF) +#define OP_PREFIX ".op_" +#else #define OP_PREFIX "op_" +#endif int do_swap; @@ -748,6 +785,7 @@ if (!data_sec) error("could not find .data section"); coff_data_shndx = data_sec - shdr; + data = sdata[coff_data_shndx]; coff_symtab = load_data(fd, fhdr.f_symptr, fhdr.f_nsyms*SYMESZ); for (i = 0, ext_sym = coff_symtab; i < nb_syms; i++, ext_sym++) { @@ -1212,10 +1250,302 @@ #endif /* CONFIG_FORMAT_MACH */ -void get_reloc_expr(char *name, int name_size, const char *sym_name) +#ifdef CONFIG_FORMAT_XCOFF + +/* XCOFF file info */ + +struct scnhdr *shdr; +uint8_t **sdata; +struct filehdr fhdr; +struct syment *xcoff_symtab; +char *strtab; +int xcoff_text_shndx, xcoff_data_shndx; +EXE_RELOC *data_relocs; +int data_nb_relocs; + +int data_shndx; + +#define STRTAB_SIZE 4 + +#define T_FUNCTION 0x20 +#define C_EXTERNAL 2 + +/* Utility functions */ + +void sym_ent_name(struct syment *ext_sym, EXE_SYM *sym) +{ + char *q; + int c, i, len; + + if (ext_sym->n_zeroes == 0) { + pstrcpy(sym->st_name, sizeof(sym->st_name), strtab + ext_sym->n_offset); + } else { + q = sym->st_name; + for(i = 0; i < SYMNMLEN; i++) { + c = ext_sym->n_name[i]; + if (c == '\0') + break; + *q++ = c; + } + *q = '\0'; + } + + /* now convert the name to a C name (suppress the leading '_') */ + if (sym->st_name[0] == '_') { + len = strlen(sym->st_name); + memmove(sym->st_name, sym->st_name + 1, len - 1); + sym->st_name[len - 1] = '\0'; + } +} + +char *name_for_dotdata(struct xcoff_rel *rel) +{ + int i; + struct xcoff_sym *sym; + uint32_t text_data; + + text_data = (uint32_t)(text + rel->xcoff_offset); + + for (i = 0, sym = symtab; i < nb_syms; i++, sym++) { + if (sym->st_syment->n_scnum == data_shndx && + text_data >= sym->st_value && + text_data < sym->st_value + sym->st_size) { + + return sym->st_name; + } + } + return NULL; +} + +static char *get_sym_name(EXE_SYM *sym) +{ + return sym->st_name; +} + +static char *get_rel_sym_name(EXE_RELOC *rel) +{ + char *name; + name = get_sym_name(symtab + rel->xcoff_reloc->r_symndx); + if (name[0] == 0) + return NULL; + if (!strcmp(name, ".data")) + name = name_for_dotdata(rel); + return name; +} + +static host_ulong get_rel_offset(EXE_RELOC *rel) +{ + return rel->xcoff_offset; +} + + +/* Used by dyngen common code */ + +struct scnhdr *find_xcoff_section(struct scnhdr *shdr, + int shnum, const char *name) { + int i; + const char *shname; + struct scnhdr *sec; + + for(i = 0; i < shnum; i++) { + sec = &shdr[i]; + if (!sec->s_name) + continue; + shname = sec->s_name; + if (!strcmp(shname, name)) + return sec; + } + return NULL; +} + +/* load a xcoff object file */ +int load_object(const char *filename) +{ + int fd; + struct scnhdr *sec, *text_sec, *data_sec; + int i; + struct syment *ext_sym; + struct reloc *xcoff_relocs; + struct reloc *ext_rel; + uint32_t *n_strtab; + EXE_SYM *sym; + EXE_RELOC *rel; const char *p; + int aux_size, j; + + fd = open(filename, O_RDONLY); + if (fd < 0) + error("can't open file '%s'", filename); + + /* Read XCOFF header. */ + if (read(fd, &fhdr, sizeof (fhdr)) != sizeof (fhdr)) + error("unable to read file header"); + + /* Check XCOFF identification. */ + if (fhdr.f_magic != U802TOCMAGIC) { + error("bad XCOFF header"); + } + do_swap = 0; + + /* read section headers */ + + shdr = load_data(fd, sizeof(struct filehdr) + fhdr.f_opthdr, + fhdr.f_nscns * sizeof(struct scnhdr)); + + /* read all section data */ + sdata = malloc(sizeof(void *) * fhdr.f_nscns); + memset(sdata, 0, sizeof(void *) * fhdr.f_nscns); + + for(i = 0;i < fhdr.f_nscns; i++) { + sec = &shdr[i]; + if (!strstart(sec->s_name, ".bss", &p)) + sdata[i] = load_data(fd, sec->s_scnptr, sec->s_size); + } + + + /* text section */ + + text_sec = find_xcoff_section(shdr, fhdr.f_nscns, ".text"); + if (!text_sec) + error("could not find .text section"); + xcoff_text_shndx = text_sec - shdr; + text = sdata[xcoff_text_shndx]; + + /* data section */ + + data_sec = find_xcoff_section(shdr, fhdr.f_nscns, ".data"); + if (!data_sec) + error("could not find .data section"); + xcoff_data_shndx = data_sec - shdr; + + xcoff_symtab = load_data(fd, fhdr.f_symptr, fhdr.f_nsyms * SYMESZ); + + n_strtab = load_data(fd, fhdr.f_symptr + fhdr.f_nsyms * SYMESZ, + STRTAB_SIZE); + strtab = load_data(fd, fhdr.f_symptr + fhdr.f_nsyms * SYMESZ, *n_strtab); + + nb_syms = fhdr.f_nsyms; + + for (i = 0, ext_sym = xcoff_symtab; i < nb_syms; + i++, ext_sym = (struct syment *)((char*)ext_sym + SYMESZ)) { + if (strstart(ext_sym->n_name, ".text", NULL)) + text_shndx = ext_sym->n_scnum; + if (strstart(ext_sym->n_name, ".data", NULL)) + data_shndx = ext_sym->n_scnum; + } + + /* set xcoff symbol */ + + symtab = malloc(sizeof(struct xcoff_sym) * nb_syms); + + for (i = 0, ext_sym = xcoff_symtab, sym = symtab; + i < nb_syms; i++, sym++, ext_sym = (struct syment *)((char*)ext_sym + SYMESZ)) { + + memset(sym, 0, sizeof(*sym)); + if (ext_sym->n_sclass == C_NULL) + continue; + if (ext_sym->n_scnum == N_DEBUG) + continue; + + sym->st_syment = ext_sym; + sym_ent_name(ext_sym, sym); + sym->st_value = ext_sym->n_value; + aux_size = ext_sym->n_numaux; + + if (ext_sym->n_scnum == text_shndx && + ISFCN(ext_sym->n_type)) { + + for (j = aux_size + 1; j < nb_syms - i; j++) { + struct syment *next_sym = (struct syment *)((char*)ext_sym + j * SYMESZ); + + if (next_sym->n_sclass != C_NULL && + next_sym->n_scnum == text_shndx && + ISFCN(next_sym->n_type)){ + sym->st_size = next_sym->n_value - ext_sym->n_value; + break; + } else if (j == nb_syms - i - 1) { + sec = &shdr[xcoff_text_shndx]; + sym->st_size = sec->s_size - ext_sym->n_value; + break; + } + } + + } else if (ext_sym->n_scnum == data_shndx && + ext_sym->n_sclass == C_EXTERNAL) { + + for (j = aux_size + 1; j < nb_syms - i; j++) { + struct syment *next_sym = (struct syment *)((char*)ext_sym + j * SYMESZ); + + if (next_sym->n_sclass != C_NULL && next_sym->n_scnum == data_shndx) { + sym->st_size = next_sym->n_value - ext_sym->n_value; + break; + } else if (j == nb_syms - i - 1) { + sec = &shdr[xcoff_data_shndx]; + sym->st_size = sec->s_size - ext_sym->n_value; + break; + } + } + } else { + sym->st_size = 0; + } + sym->st_type = ext_sym->n_type; + sym->st_shndx = ext_sym->n_scnum; + } + + /* find text relocations */ + + sec = &shdr[xcoff_text_shndx]; + xcoff_relocs = load_data(fd, sec->s_relptr, sec->s_nreloc * RELSZ); + nb_relocs = sec->s_nreloc; + + /* set xcoff relocation */ + + relocs = malloc(sizeof(struct xcoff_rel) * nb_relocs); + for (i = 0, ext_rel = xcoff_relocs, rel = relocs; i < nb_relocs; + i++, ext_rel = (struct reloc *)((char*)ext_rel + RELSZ), rel++) { + memset(rel, 0, sizeof(*rel)); + rel->xcoff_reloc = ext_rel; + rel->xcoff_offset = ext_rel->r_vaddr; + rel->xcoff_size = ext_rel->r_rsize; + rel->xcoff_type = ext_rel->r_rtype; + } + /* find data relocations */ + + sec = &shdr[xcoff_data_shndx]; + xcoff_relocs = load_data(fd, sec->s_relptr, sec->s_nreloc * RELSZ); + data_nb_relocs = sec->s_nreloc; + + /* set xcoff relocation */ + + data_relocs = malloc(sizeof(struct xcoff_rel) * data_nb_relocs); + for (i = 0, ext_rel = xcoff_relocs, rel = data_relocs; i < data_nb_relocs; + i++, ext_rel = (struct reloc *)((char*)ext_rel + RELSZ), rel++) { + memset(rel, 0, sizeof(*rel)); + rel->xcoff_reloc = ext_rel; + rel->xcoff_offset = ext_rel->r_vaddr; + rel->xcoff_size = ext_rel->r_rsize; + rel->xcoff_type = ext_rel->r_rtype; + } + return 0; +} +#endif + +void get_reloc_expr(char *name, int name_size, const char *sym_name) +{ + const char *p; +#if defined(CONFIG_FORMAT_XCOFF) + if (strstart(sym_name, "_op_param", &p)) { + snprintf(name, name_size, "param%s", p); + } else if (strstart(sym_name, ".__op_gen_label", &p)) { + snprintf(name, name_size, "gen_labels[param%s]", p); + } else if (sym_name[0] == '.') { + snprintf(name, name_size, "(long)*(void**)(%s)", sym_name + 1); + } else { + snprintf(name, name_size, "(long)(&%s)", sym_name); + } +#else if (strstart(sym_name, "__op_param", &p)) { snprintf(name, name_size, "param%s", p); } else if (strstart(sym_name, "__op_gen_label", &p)) { @@ -1230,6 +1560,7 @@ #endif snprintf(name, name_size, "(long)(&%s)", sym_name); } +#endif } #ifdef HOST_IA64 @@ -1480,6 +1811,42 @@ } #endif #elif defined(HOST_PPC) +#ifdef CONFIG_FORMAT_XCOFF + { + uint8_t *p; + uint32_t inst; + signed short disp; + name ++; /* remove first '.' */ + /* -O2 doesn't remove stack management, we do */ + disp = 0; + /* stwu r1,x(r1) */ + inst = get32((uint32_t *)p_start); + if ((inst & 0xFFFF0000) == 0x94210000) { + disp = -(short)(inst & 0x0000FFFF); + start_offset += 4; + p_start += 4; + } + p = (void*)(p_end - 4); + if (p == p_start) + error("empty code for %s", name); + /* blr */ + while (get32((uint32_t *)p) != 0x4e800020) { + p -= 4; + if (p <= p_start) + error("blr expected at the end of %s [0x%p-0x%p]", name, p_start - start_offset, p_end); + } + inst = get32((uint32_t *)(p - 4)); + if (disp !=0) { + /* addi r1,r1,x */ + if ((inst & 0xFFFF0000) != 0x38210000) + error("addi r1,r1,x expected at end of %s\n", name); + if (disp != (short)(inst & 0x0000FFFF)) + error("Bad stack management for %s", name); + p -= 4; + } + copy_size = p - p_start; + } +#else { uint8_t *p; p = (void *)(p_end - 4); @@ -1489,6 +1856,7 @@ error("blr expected at the end of %s", name); copy_size = p - p_start; } +#endif #elif defined(HOST_S390) { uint8_t *p; @@ -1691,8 +2059,13 @@ sym_name = get_rel_sym_name(rel); if(!sym_name) continue; +#if defined(CONFIG_FORMAT_XCOFF) + if (strstart(sym_name, "_op_param", &p) || + strstart(sym_name, ".__op_gen_label", &p)) { +#else if (strstart(sym_name, "__op_param", &p) || strstart(sym_name, "__op_gen_label", &p)) { +#endif n = strtoul(p, NULL, 10); if (n > MAX_ARGS) error("too many arguments in %s", name); @@ -1737,6 +2110,19 @@ sym_name = get_rel_sym_name(rel); if(!sym_name) continue; +#if defined(CONFIG_FORMAT_XCOFF) + if (*sym_name && + !strstart(sym_name, "_op_param", NULL) && + !strstart(sym_name, ".__op_jmp", NULL) && + !strstart(sym_name, ".__op_gen_label", NULL)) { + if (sym_name[0] == '.') + sym_name++; + if (rel->xcoff_type == R_RBR) + fprintf(outfile, " extern void %s();\n", sym_name); + else if (rel->xcoff_type != R_TOC) + fprintf(outfile, " extern char %s;\n", sym_name); + } +#else if (*sym_name && !strstart(sym_name, "__op_param", NULL) && !strstart(sym_name, "__op_jmp", NULL) && @@ -1763,14 +2149,20 @@ fprintf(outfile, " extern char %s;\n", sym_name); #else - fprintf(outfile, "extern char %s;\n", sym_name); -#endif + fprintf(outfile, " extern char %s;\n", sym_name); } +#endif +#endif } } +#if defined(_AIX) + fprintf(outfile, " memcpy(gen_code_ptr, (void*)((*(void **)%s) + %d), %d);\n", + name, (int)(start_offset - offset), copy_size); +#else fprintf(outfile, " memcpy(gen_code_ptr, (void *)((char *)&%s+%d), %d);\n", name, (int)(start_offset - offset), copy_size); +#endif /* emit code offset information */ { @@ -1781,10 +2173,13 @@ for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { sym_name = get_sym_name(sym); +#if defined(CONFIG_FORMAT_XCOFF) + if (strstart(sym_name, ".__op_label", &p)) { +#else if (strstart(sym_name, "__op_label", &p)) { +#endif uint8_t *ptr; unsigned long offset; - /* test if the variable refers to a label inside the code we are generating */ #ifdef CONFIG_FORMAT_COFF @@ -1799,6 +2194,14 @@ if(!sym->n_sect) continue; ptr = sdata[sym->n_sect-1]; +#elif defined(CONFIG_FORMAT_XCOFF) + if (sym->st_shndx == text_shndx) { + ptr = sdata[xcoff_text_shndx]; + } else if (sym->st_shndx == data_shndx) { + ptr = sdata[xcoff_data_shndx]; + } else { + ptr = NULL; + } #else ptr = sdata[sym->st_shndx]; #endif @@ -1808,8 +2211,7 @@ #ifdef CONFIG_FORMAT_MACH offset -= section_hdr[sym->n_sect-1].addr; #endif - val = *(host_ulong *)(ptr + offset); -#ifdef ELF_USES_RELOCA +#if defined(ELF_USES_RELOCA) { int reloc_shndx, nb_relocs1, j; @@ -1828,6 +2230,10 @@ } } } +#elif defined(CONFIG_FORMAT_XCOFF) + val = (host_ulong)offset; +#else + val = *(host_ulong *)(ptr + offset); #endif if (val >= start_offset && val <= start_offset + copy_size) { n = strtol(p, NULL, 10); @@ -2089,6 +2495,65 @@ error("unsupported powerpc relocation (%d)", type); } } +#elif defined(CONFIG_FORMAT_XCOFF) + char relname[256]; + int sign, len; + int reloc_offset; + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { + + if (rel->xcoff_offset >= start_offset && + rel->xcoff_offset < start_offset + copy_size) { + sym_name = get_rel_sym_name(rel); + if (!sym_name) + continue; + + reloc_offset = rel->xcoff_offset - start_offset; + if (strstart(sym_name, ".__op_jmp", &p)) { + int n; + n = strtol(p, NULL, 10); + /* .__op_jmp relocations are done at + runtime to do translated block + chaining: the offset of the instruction + needs to be stored */ + fprintf(outfile, " jmp_offsets[%d] = %d + (gen_code_ptr - gen_code_buf);\n", n, reloc_offset); + continue; + } + get_reloc_expr(relname, sizeof(relname), sym_name); + len = (rel->xcoff_size & R_LEN) + 1; + sign = (rel->xcoff_size & R_SIGN) ? -1 : 1; + switch(rel->xcoff_type) { + case R_ABS: + break; + case R_TOC: + if (strstart(sym_name, "_op_param", NULL)) { + /* create "lis %0, param@h" with %0 from next opcode */ + fprintf(outfile, +" *(uint16_t *)(gen_code_ptr + %d - 2) = 0x3c00 | " +"(*(uint16_t *)(gen_code_ptr + %d + 2) & 0x03e0);\n", +reloc_offset, reloc_offset); + fprintf(outfile, +" *(uint16_t *)(gen_code_ptr + %d) = %s >> 16;\n", +reloc_offset, relname); + /* update "ori %0,%0,param@l" */ + fprintf(outfile, +" *(uint16_t *)(gen_code_ptr + %d + 4) = %s & 0xffff;\n", +reloc_offset, relname); + } + break; + case R_RBR: + fprintf(outfile, +" *(uint32_t *)(gen_code_ptr + %d) = " + "(*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | " + "((%s - (long)(gen_code_ptr + %d)) & 0x03fffffc);\n", + reloc_offset, reloc_offset, relname, reloc_offset); + break; + default: + error("unsupported XCOFF relocation type (%x)\n", + rel->xcoff_type); + break; + } + } + } #else #error unsupport object format #endif @@ -2658,7 +3123,7 @@ const char *name; name = get_sym_name(sym); if (strstart(name, OP_PREFIX, NULL)) { -#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF) +#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF) || defined(CONFIG_FORMAT_XCOFF) if (sym->st_shndx != text_shndx) error("invalid section for opcode (0x%x)", sym->st_shndx); #endif @@ -2824,7 +3289,7 @@ printf("%4d: %s pos=0x%08x len=%d\n", i, name, sym->st_value, sym->st_size); #endif -#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF) +#if defined(CONFIG_FORMAT_ELF) || defined(CONFIG_FORMAT_COFF) || defined(CONFIG_FORMAT_XCOFF) if (sym->st_shndx != text_shndx) error("invalid section for opcode (0x%x)", sym->st_shndx); #endif Index: qemu-0.9.1-aix/Makefile.target =================================================================== --- qemu-0.9.1-aix.orig/Makefile.target 2008-04-09 20:25:14.000000000 +0200 +++ qemu-0.9.1-aix/Makefile.target 2008-04-09 20:26:10.-661130200 +0200 @@ -73,6 +73,7 @@ PROGS=$(QEMU_PROG) # We require -O2 to avoid the stack setup prologue in EXIT_TB +# (except for AIX...) OP_CFLAGS := -Wall -O2 -g -fno-strict-aliasing # cc-option @@ -90,6 +91,10 @@ OP_CFLAGS+=$(call cc-option, -fno-align-jumps, "") OP_CFLAGS+=$(call cc-option, -fno-align-functions, $(call cc-option, -malign-functions=0, "")) OP_CFLAGS+=$(call cc-option, -fno-section-anchors, "") +ifdef CONFIG_AIX +OP_CFLAGS+=$(call cc-option, -mlongcall, "") +OP_CFLAGS+=$(call cc-option, -mno-sched-prolog, "") +endif HELPER_CFLAGS= @@ -153,7 +158,12 @@ LDFLAGS+=$(OS_LDFLAGS) $(ARCH_LDFLAGS) OP_CFLAGS+=$(OS_CFLAGS) $(ARCH_CFLAGS) -CPPFLAGS+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +CPPFLAGS+=-D_GNU_SOURCE +ifdef CONFIG_AIX +CPPFLAGS+= -D_LARGE_FILES +else +CPPFLAGS+= -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif LIBS+=-lm ifdef CONFIG_WIN32 LIBS+=-lwinmm -lws2_32 -liphlpapi @@ -613,10 +623,12 @@ ifndef CONFIG_DARWIN ifndef CONFIG_WIN32 ifndef CONFIG_SOLARIS +ifndef CONFIG_AIX LIBS+=-lutil endif endif endif +endif ifdef TARGET_GPROF vl.o: CFLAGS+=-p LDFLAGS+=-p Index: qemu-0.9.1-aix/osdep.c =================================================================== --- qemu-0.9.1-aix.orig/osdep.c 2008-04-09 20:24:36.000000000 +0200 +++ qemu-0.9.1-aix/osdep.c 2008-04-09 20:25:40.992782320 +0200 @@ -199,7 +199,7 @@ if (kqemu_allowed) return kqemu_vmalloc(size); #endif -#ifdef _BSD +#if defined(_BSD) || defined(_AIX) return valloc(size); #else return memalign(4096, size); Index: qemu-0.9.1-aix/dyngen-exec.h =================================================================== --- qemu-0.9.1-aix.orig/dyngen-exec.h 2008-04-09 20:24:36.000000000 +0200 +++ qemu-0.9.1-aix/dyngen-exec.h 2008-04-09 20:25:40.-482479160 +0200 @@ -237,12 +237,34 @@ #else extern int __op_param1, __op_param2, __op_param3; #endif +#if defined(_AIX) +asm("\t.toc\n" + "__op_param1_toc:\n" + "\t.tc __op_param1[TC],__op_param1[RW]\n" + "__op_param2_toc:\n" + "\t.tc __op_param2[TC],__op_param2[RW]\n" + "__op_param3_toc:\n" + "\t.tc __op_param3[TC],__op_param3[RW]\n" + "\t.csect .text[PR]\n"); + +#define PARAM1 ({ long _r; asm("lwz %0,"ASM_NAME(__op_param1_toc)"(2); ori %0,%0,0" : "=r" (_r) : ); _r; }) +#define PARAM2 ({ long _r; asm("lwz %0,"ASM_NAME(__op_param2_toc)"(2); ori %0,%0,0" : "=r" (_r) : ); _r; }) +#define PARAM3 ({ long _r; asm("lwz %0,"ASM_NAME(__op_param3_toc)"(2); ori %0,%0,0" : "=r" (_r) : ); _r; }) +#else #define PARAM1 ((long)(&__op_param1)) #define PARAM2 ((long)(&__op_param2)) #define PARAM3 ((long)(&__op_param3)) +#endif #endif /* !defined(__alpha__) */ +#if defined(_AIX) +extern void __op_jmp0(void); +extern void __op_jmp1(void); +extern void __op_jmp2(void); +extern void __op_jmp3(void); +#else extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; +#endif #if defined(_WIN32) || defined(__APPLE__) #define ASM_NAME(x) "_" #x @@ -258,7 +280,11 @@ #define GOTO_LABEL_PARAM(n) asm volatile ("jmp " ASM_NAME(__op_gen_label) #n) #elif defined(__powerpc__) #define EXIT_TB() asm volatile ("blr") +#if defined(_AIX) +#define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(.__op_gen_label) #n) +#else #define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n) +#endif #elif defined(__s390__) #define EXIT_TB() asm volatile ("br %r14") #define GOTO_LABEL_PARAM(n) asm volatile ("larl %r7,12; l %r7,0(%r7); br %r7; .long " ASM_NAME(__op_gen_label) #n) Index: qemu-0.9.1-aix/dyngen.h =================================================================== --- qemu-0.9.1-aix.orig/dyngen.h 2008-04-09 20:24:36.000000000 +0200 +++ qemu-0.9.1-aix/dyngen.h 2008-04-09 20:25:40.-1950107640 +0200 @@ -19,14 +19,21 @@ */ int __op_param1, __op_param2, __op_param3; -#if defined(__sparc__) || defined(__arm__) +#if defined(__sparc__) || defined(__arm__) || defined(_AIX) void __op_gen_label1(){} void __op_gen_label2(){} void __op_gen_label3(){} #else int __op_gen_label1, __op_gen_label2, __op_gen_label3; #endif +#if defined(_AIX) +void __op_jmp0(void) { } +void __op_jmp1(void) { } +void __op_jmp2(void) { } +void __op_jmp3(void) { } +#else int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; +#endif #if defined(__i386__) || defined(__x86_64__) || defined(__s390__) static inline void flush_icache_range(unsigned long start, unsigned long stop) Index: qemu-0.9.1-aix/block-qcow2.c =================================================================== --- qemu-0.9.1-aix.orig/block-qcow2.c 2008-04-09 20:24:36.000000000 +0200 +++ qemu-0.9.1-aix/block-qcow2.c 2008-04-09 20:25:40.-2021367712 +0200 @@ -1386,6 +1386,8 @@ uint32_t extra_data_size; offset = s->snapshots_offset; + if (s->nb_snapshots == 0) + goto out; s->snapshots = qemu_mallocz(s->nb_snapshots * sizeof(QCowSnapshot)); if (!s->snapshots) goto fail; @@ -1424,6 +1426,7 @@ offset += name_size; sn->name[name_size] = '\0'; } +out: s->snapshots_size = offset - s->snapshots_offset; return 0; fail: Index: qemu-0.9.1-aix/cpu-exec.c =================================================================== --- qemu-0.9.1-aix.orig/cpu-exec.c 2008-04-09 20:25:14.000000000 +0200 +++ qemu-0.9.1-aix/cpu-exec.c 2008-04-09 20:25:40.-611230304 +0200 @@ -735,6 +735,17 @@ fp.ip = tc_ptr; fp.gp = code_gen_buffer + 2 * (1 << 20); (*(void (*)(void)) &fp)(); +#elif defined(_AIX) + asm volatile ("mtctr %0\n" + "stwu 1,-512(1)\n" + "bctrl\n" + "addi 1,1,512\n" + : : "r" (tc_ptr) + : "r3", "r4", "r5", "r6", "r7", "r8", + "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", + "r23", "r24", "r25", "r26", "r27", "r28", "r29", + "r30", "r31", "lr", "ctr"); #else gen_func(); #endif Index: qemu-0.9.1-aix/target-ppc/op.c =================================================================== --- qemu-0.9.1-aix.orig/target-ppc/op.c 2008-04-09 20:24:36.000000000 +0200 +++ qemu-0.9.1-aix/target-ppc/op.c 2008-04-09 20:25:40.-676334376 +0200 @@ -25,6 +25,7 @@ #include "host-utils.h" #include "helper_regs.h" #include "op_helper.h" +#undef hz #define REG 0 #include "op_template.h" Index: qemu-0.9.1-aix/target-ppc/translate.c =================================================================== --- qemu-0.9.1-aix.orig/target-ppc/translate.c 2008-04-09 20:24:36.000000000 +0200 +++ qemu-0.9.1-aix/target-ppc/translate.c 2008-04-09 20:25:41.-12379480 +0200 @@ -21,7 +21,9 @@ #include #include #include +#include #include +#undef hz #include "cpu.h" #include "exec-all.h" Index: qemu-0.9.1-aix/Makefile =================================================================== --- qemu-0.9.1-aix.orig/Makefile 2008-04-09 20:25:14.000000000 +0200 +++ qemu-0.9.1-aix/Makefile 2008-04-09 20:25:41.1331741856 +0200 @@ -11,7 +11,12 @@ LDFLAGS += $(OS_LDFLAGS) $(ARCH_LDFLAGS) CPPFLAGS += -I. -I$(SRC_PATH) -MMD -MP -CPPFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +CPPFLAGS += -D_GNU_SOURCE +ifdef CONFIG_AIX +CPPFLAGS += -DLARGE_FILES +else +CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif LIBS= ifdef CONFIG_STATIC LDFLAGS += -static