static int register_libraries(int fd, const char* build, const char* project, const char* filename, int* isMachO) { ssize_t res; uint32_t magic; res = read(fd, &magic, sizeof(uint32_t)); if (res < sizeof(uint32_t)) { goto error_out; } if (magic == FAT_MAGIC || magic == FAT_CIGAM) { struct fat_header fh; int swap = 0; res = read(fd, &fh.nfat_arch, sizeof(struct fat_header) - sizeof(uint32_t)); if (res < sizeof(uint32_t)) { goto error_out; } if (magic == FAT_CIGAM) { swap = 1; swap_fat_header(&fh, NXHostByteOrder()); } int i; for (i = 0; i < fh.nfat_arch; ++i) { struct fat_arch fa; res = read(fd, &fa, sizeof(fa)); if (res < sizeof(fa)) { goto error_out; } if (swap) swap_fat_arch(&fa, 1, NXHostByteOrder()); off_t save = lseek(fd, 0, SEEK_CUR); lseek(fd, (off_t)fa.offset, SEEK_SET); register_mach_header(build, project, filename, &fa, fd, isMachO); lseek(fd, save, SEEK_SET); } } else { lseek(fd, 0, SEEK_SET); register_mach_header(build, project, filename, NULL, fd, isMachO); } error_out: return 0; }
/** * \fn moa_error_t moa_read_fat_section(struct s_mach_file* ptr_mach_file) * \brief Read the fat section of a mach_file (fat_header + fat_arch). * * \param ptr_mach_file Pointer to mach archive. * * \return MOA_SUCCESS if all succeed, else error number. */ moa_error_t moa_read_fat_section(struct s_mach_file* ptr_mach_file) { if (NULL == ptr_mach_file) return MOA_ERR_NULLPTR; /// Reset file offset lseek(ptr_mach_file->fd, (off_t)0, SEEK_SET); /// Read the fat header const size_t mach_header_size = sizeof(ptr_mach_file->fat_section.fat_header); if (read(ptr_mach_file->fd, &ptr_mach_file->fat_section.fat_header, mach_header_size) != (ssize_t)mach_header_size) return MOA_ERR_READ_FAT_HEADER; /// Check if the file is actually a mach archive if (!moa_is_mach_archive(ptr_mach_file)) return MOA_ERR_NOT_MACH_ARCHIVE; /// Get host machine byte order /// If intel CPU, we need to change the byte order to lil endian enum NXByteOrder host_byte_order = NXHostByteOrder(); if (NX_LittleEndian == host_byte_order) swap_fat_header(&ptr_mach_file->fat_section.fat_header, NX_LittleEndian); else if (NX_UnknownByteOrder == NXHostByteOrder()) return MOA_ERR_UNKNOW_ARCH; /// Read the N fat archs if (ptr_mach_file->fat_section.fat_archs != NULL) free(ptr_mach_file->fat_section.fat_archs); const size_t fat_arch_size = ptr_mach_file->fat_section.fat_header.nfat_arch * sizeof(*ptr_mach_file->fat_section.fat_archs); if (NULL == (ptr_mach_file->fat_section.fat_archs = (struct fat_arch*)malloc(fat_arch_size))) return MOA_ERR_READ_FAT_ARCH; if (read(ptr_mach_file->fd, ptr_mach_file->fat_section.fat_archs, fat_arch_size) != (ssize_t)fat_arch_size) return MOA_ERR_READ_FAT_ARCH; if (NX_LittleEndian == host_byte_order) swap_fat_arch(ptr_mach_file->fat_section.fat_archs, ptr_mach_file->fat_section.fat_header.nfat_arch, NX_LittleEndian); return MOA_SUCCESS; }
boolean_t macho_swap_64( u_char * file) { boolean_t result = FALSE; struct mach_header_64 *hdr = (struct mach_header_64 *) file; struct load_command *lc = (struct load_command *) &hdr[1]; struct segment_command_64 *seg = NULL; u_long offset = 0; u_int cmd = 0; u_int cmdsize = 0; u_int i = 0; if (!hdr || hdr->magic != MH_CIGAM_64) goto finish; swap_mach_header_64(hdr, NXHostByteOrder()); offset = sizeof(*hdr); for (i = 0; i < hdr->ncmds; ++i) { lc = (struct load_command *) (file + offset); cmd = OSSwapInt32(lc->cmd); cmdsize = OSSwapInt32(lc->cmdsize); offset += cmdsize; if (cmd == LC_SEGMENT_64) { seg = (struct segment_command_64 *) lc; swap_segment_command_64(seg, NXHostByteOrder()); } else { swap_load_command(lc, NXHostByteOrder()); } } result = TRUE; finish: return result; }
void swap_x86_thread_state( x86_thread_state_t *cpu, enum NXByteOrder target_byte_sex) { x86_state_hdr_t hdr; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); hdr = cpu->tsh; if(target_byte_sex == host_byte_sex) swap_x86_state_hdr(&hdr, host_byte_sex); swap_x86_state_hdr(&cpu->tsh, target_byte_sex); if(hdr.flavor == x86_THREAD_STATE32) swap_i386_thread_state(&cpu->uts.ts32, target_byte_sex); else if(hdr.flavor == x86_THREAD_STATE64) swap_x86_thread_state64(&cpu->uts.ts64, target_byte_sex); }
void swap_x86_float_state( x86_float_state_t *fpu, enum NXByteOrder target_byte_sex) { x86_state_hdr_t hdr; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); hdr = fpu->fsh; if(target_byte_sex == host_byte_sex) swap_x86_state_hdr(&hdr, host_byte_sex); swap_x86_state_hdr(&fpu->fsh, target_byte_sex); if(hdr.flavor == x86_FLOAT_STATE32) swap_i386_float_state(&fpu->ufs.fs32, target_byte_sex); else if(hdr.flavor == x86_FLOAT_STATE64) swap_x86_float_state64(&fpu->ufs.fs64, target_byte_sex); }
void swap_x86_exception_state( x86_exception_state_t *exc, enum NXByteOrder target_byte_sex) { x86_state_hdr_t hdr; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); hdr = exc->esh; if(target_byte_sex == host_byte_sex) swap_x86_state_hdr(&hdr, host_byte_sex); swap_x86_state_hdr(&exc->esh, target_byte_sex); if(hdr.flavor == x86_EXCEPTION_STATE32) swap_i386_exception_state(&exc->ues.es32, target_byte_sex); else if(hdr.flavor == x86_EXCEPTION_STATE64) swap_x86_exception_state64(&exc->ues.es64, target_byte_sex); }
void swap_x86_debug_state( x86_debug_state_t *debug, enum NXByteOrder target_byte_sex) { x86_state_hdr_t hdr; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); hdr = debug->dsh; if(target_byte_sex == host_byte_sex) swap_x86_state_hdr(&hdr, host_byte_sex); swap_x86_state_hdr(&debug->dsh, target_byte_sex); if(hdr.flavor == x86_DEBUG_STATE32) swap_x86_debug_state32(&debug->uds.ds32, target_byte_sex); else if(hdr.flavor == x86_DEBUG_STATE64) swap_x86_debug_state64(&debug->uds.ds64, target_byte_sex); }
boolean_t macho_unswap_32( u_char * file) { boolean_t result = FALSE; enum NXByteOrder order = 0; struct mach_header *hdr = (struct mach_header *) file; struct load_command *lc = (struct load_command *) &hdr[1]; struct segment_command *seg = NULL; u_long offset = 0; u_int i = 0; if (NXHostByteOrder() == NX_LittleEndian) { order = NX_BigEndian; } else { order = NX_LittleEndian; } if (!hdr || hdr->magic != MH_MAGIC) goto finish; offset = sizeof(*hdr); for (i = 0; i < hdr->ncmds; ++i) { lc = (struct load_command *) (file + offset); offset += lc->cmdsize; if (lc->cmd == LC_SEGMENT) { seg = (struct segment_command *) lc; swap_segment_command(seg, order); } else { swap_load_command(lc, order); } } swap_mach_header(hdr, order); result = TRUE; finish: return result; }
void swap_dylib_reference( struct dylib_reference *refs, uint32_t nrefs, enum NXByteOrder target_byte_sex) { struct swapped_dylib_reference { union { struct { uint32_t flags:8, isym:24; } fields; uint32_t word; } u; } sref; uint32_t i; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); for(i = 0; i < nrefs; i++){ if(target_byte_sex == host_byte_sex){ memcpy(&sref, refs + i, sizeof(struct swapped_dylib_reference)); sref.u.word = OSSwapInt32(sref.u.word); refs[i].flags = sref.u.fields.flags; refs[i].isym = sref.u.fields.isym; } else{ sref.u.fields.isym = refs[i].isym; sref.u.fields.flags = refs[i].flags; sref.u.word = OSSwapInt32(sref.u.word); memcpy(refs + i, &sref, sizeof(struct swapped_dylib_reference)); } } }
void swap_x86_float_state( x86_float_state_t *fpu, enum NXByteOrder target_byte_sex) { x86_state_hdr_t hdr; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); hdr = fpu->fsh; if(target_byte_sex == host_byte_sex) swap_x86_state_hdr(&hdr, host_byte_sex); swap_x86_state_hdr(&fpu->fsh, target_byte_sex); /* current i386 thread states */ #if i386_THREAD_STATE == 1 if(hdr.flavor == x86_FLOAT_STATE32) swap_i386_float_state(&fpu->ufs.fs32, target_byte_sex); else #endif if(hdr.flavor == x86_FLOAT_STATE64) swap_x86_float_state64(&fpu->ufs.fs64, target_byte_sex); }
void swap_x86_exception_state( x86_exception_state_t *exc, enum NXByteOrder target_byte_sex) { x86_state_hdr_t hdr; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); hdr = exc->esh; if(target_byte_sex == host_byte_sex) swap_x86_state_hdr(&hdr, host_byte_sex); swap_x86_state_hdr(&exc->esh, target_byte_sex); /* current i386 thread states */ #if i386_THREAD_STATE == 1 if(hdr.flavor == x86_EXCEPTION_STATE32) swap_i386_exception_state(&exc->ues.es32, target_byte_sex); else #endif if(hdr.flavor == x86_EXCEPTION_STATE64) swap_x86_exception_state64(&exc->ues.es64, target_byte_sex); }
void swap_i386_thread_fpstate( i386_thread_fpstate_t *fpu, enum NXByteOrder target_byte_sex) { struct swapped_fp_control { union { struct { unsigned short :3, /*inf*/ :1, rc :2, pc :2, :2, precis :1, undfl :1, ovrfl :1, zdiv :1, denorm :1, invalid :1; } fields; unsigned short half; } u; } sfpc; struct swapped_fp_status { union { struct { unsigned short busy :1, c3 :1, tos :3, c2 :1, c1 :1, c0 :1, errsumm :1, stkflt :1, precis :1, undfl :1, ovrfl :1, zdiv :1, denorm :1, invalid :1; } fields; unsigned short half; } u; } sfps; struct swapped_fp_tag { union { struct { unsigned short tag7 :2, tag6 :2, tag5 :2, tag4 :2, tag3 :2, tag2 :2, tag1 :2, tag0 :2; } fields; unsigned short half; } u; } sfpt; struct swapped_fp_data_reg { unsigned short mant; unsigned short mant1 :16, mant2 :16, mant3 :16; union { struct { unsigned short sign :1, exp :15; } fields; unsigned short half; } u; } sfpd; struct swapped_sel { union { struct { unsigned short index :13, ti :1, rpl :2; } fields; unsigned short half; } u; } ss; enum NXByteOrder host_byte_sex; unsigned long i; host_byte_sex = NXHostByteOrder(); fpu->environ.ip = NXSwapLong(fpu->environ.ip); fpu->environ.opcode = NXSwapShort(fpu->environ.opcode); fpu->environ.dp = NXSwapLong(fpu->environ.dp); if(target_byte_sex == host_byte_sex) { memcpy(&sfpc, &(fpu->environ.control), sizeof(struct swapped_fp_control)); sfpc.u.half = NXSwapShort(sfpc.u.half); fpu->environ.control.rc = sfpc.u.fields.rc; fpu->environ.control.pc = sfpc.u.fields.pc; fpu->environ.control.precis = sfpc.u.fields.precis; fpu->environ.control.undfl = sfpc.u.fields.undfl; fpu->environ.control.ovrfl = sfpc.u.fields.ovrfl; fpu->environ.control.zdiv = sfpc.u.fields.zdiv; fpu->environ.control.denorm = sfpc.u.fields.denorm; fpu->environ.control.invalid = sfpc.u.fields.invalid; memcpy(&sfps, &(fpu->environ.status), sizeof(struct swapped_fp_status)); sfps.u.half = NXSwapShort(sfps.u.half); fpu->environ.status.busy = sfps.u.fields.busy; fpu->environ.status.c3 = sfps.u.fields.c3; fpu->environ.status.tos = sfps.u.fields.tos; fpu->environ.status.c2 = sfps.u.fields.c2; fpu->environ.status.c1 = sfps.u.fields.c1; fpu->environ.status.c0 = sfps.u.fields.c0; fpu->environ.status.errsumm = sfps.u.fields.errsumm; fpu->environ.status.stkflt = sfps.u.fields.stkflt; fpu->environ.status.precis = sfps.u.fields.precis; fpu->environ.status.undfl = sfps.u.fields.undfl; fpu->environ.status.ovrfl = sfps.u.fields.ovrfl; fpu->environ.status.zdiv = sfps.u.fields.zdiv; fpu->environ.status.denorm = sfps.u.fields.denorm; fpu->environ.status.invalid = sfps.u.fields.invalid; memcpy(&sfpt, &(fpu->environ.tag), sizeof(struct swapped_fp_tag)); sfpt.u.half = NXSwapShort(sfpt.u.half); fpu->environ.tag.tag7 = sfpt.u.fields.tag7; fpu->environ.tag.tag6 = sfpt.u.fields.tag6; fpu->environ.tag.tag5 = sfpt.u.fields.tag5; fpu->environ.tag.tag4 = sfpt.u.fields.tag4; fpu->environ.tag.tag3 = sfpt.u.fields.tag3; fpu->environ.tag.tag2 = sfpt.u.fields.tag2; fpu->environ.tag.tag1 = sfpt.u.fields.tag1; fpu->environ.tag.tag0 = sfpt.u.fields.tag0; memcpy(&ss, &(fpu->environ.cs), sizeof(struct swapped_sel)); ss.u.half = NXSwapShort(ss.u.half); fpu->environ.cs.index = ss.u.fields.index; fpu->environ.cs.ti = ss.u.fields.ti; fpu->environ.cs.rpl = ss.u.fields.rpl; memcpy(&ss, &(fpu->environ.ds), sizeof(struct swapped_sel)); ss.u.half = NXSwapShort(ss.u.half); fpu->environ.ds.index = ss.u.fields.index; fpu->environ.ds.ti = ss.u.fields.ti; fpu->environ.ds.rpl = ss.u.fields.rpl; for(i = 0; i < 8; i++) { memcpy(&sfpd, &(fpu->stack.ST[i]), sizeof(struct swapped_fp_data_reg)); fpu->stack.ST[i].mant = NXSwapShort(sfpd.mant); fpu->stack.ST[i].mant1 = NXSwapShort(sfpd.mant1); fpu->stack.ST[i].mant2 = NXSwapShort(sfpd.mant2); fpu->stack.ST[i].mant3 = NXSwapShort(sfpd.mant3); sfpd.u.half = NXSwapShort(sfpd.u.half); fpu->stack.ST[i].exp = sfpd.u.fields.exp; fpu->stack.ST[i].sign = sfpd.u.fields.sign; } } else { sfpc.u.fields.rc = fpu->environ.control.rc; sfpc.u.fields.pc = fpu->environ.control.pc; sfpc.u.fields.precis = fpu->environ.control.precis; sfpc.u.fields.undfl = fpu->environ.control.undfl; sfpc.u.fields.ovrfl = fpu->environ.control.ovrfl; sfpc.u.fields.zdiv = fpu->environ.control.zdiv; sfpc.u.fields.denorm = fpu->environ.control.denorm; sfpc.u.fields.invalid = fpu->environ.control.invalid; sfpc.u.half = NXSwapShort(sfpc.u.half); memcpy(&(fpu->environ.control), &sfpc, sizeof(struct swapped_fp_control)); sfps.u.fields.busy = fpu->environ.status.busy; sfps.u.fields.c3 = fpu->environ.status.c3; sfps.u.fields.tos = fpu->environ.status.tos; sfps.u.fields.c2 = fpu->environ.status.c2; sfps.u.fields.c1 = fpu->environ.status.c1; sfps.u.fields.c0 = fpu->environ.status.c0; sfps.u.fields.errsumm = fpu->environ.status.errsumm; sfps.u.fields.stkflt = fpu->environ.status.stkflt; sfps.u.fields.precis = fpu->environ.status.precis; sfps.u.fields.undfl = fpu->environ.status.undfl; sfps.u.fields.ovrfl = fpu->environ.status.ovrfl; sfps.u.fields.zdiv = fpu->environ.status.zdiv; sfps.u.fields.denorm = fpu->environ.status.denorm; sfps.u.fields.invalid = fpu->environ.status.invalid; sfps.u.half = NXSwapShort(sfps.u.half); memcpy(&(fpu->environ.status), &sfps, sizeof(struct swapped_fp_status)); sfpt.u.fields.tag7 = fpu->environ.tag.tag7; sfpt.u.fields.tag6 = fpu->environ.tag.tag6; sfpt.u.fields.tag5 = fpu->environ.tag.tag5; sfpt.u.fields.tag4 = fpu->environ.tag.tag4; sfpt.u.fields.tag3 = fpu->environ.tag.tag3; sfpt.u.fields.tag2 = fpu->environ.tag.tag2; sfpt.u.fields.tag1 = fpu->environ.tag.tag1; sfpt.u.fields.tag0 = fpu->environ.tag.tag0; sfpt.u.half = NXSwapShort(sfpt.u.half); memcpy(&(fpu->environ.tag), &sfpt, sizeof(struct swapped_fp_tag)); ss.u.fields.index = fpu->environ.cs.index; ss.u.fields.ti = fpu->environ.cs.ti; ss.u.fields.rpl = fpu->environ.cs.rpl; ss.u.half = NXSwapShort(ss.u.half); memcpy(&(fpu->environ.cs), &ss, sizeof(struct swapped_sel)); ss.u.fields.index = fpu->environ.ds.index; ss.u.fields.ti = fpu->environ.ds.ti; ss.u.fields.rpl = fpu->environ.ds.rpl; ss.u.half = NXSwapShort(ss.u.half); memcpy(&(fpu->environ.cs), &ss, sizeof(struct swapped_sel)); for(i = 0; i < 8; i++) { sfpd.mant = NXSwapShort(fpu->stack.ST[i].mant); sfpd.mant1 = NXSwapShort(fpu->stack.ST[i].mant1); sfpd.mant2 = NXSwapShort(fpu->stack.ST[i].mant2); sfpd.mant3 = NXSwapShort(fpu->stack.ST[i].mant3); sfpd.u.fields.exp = fpu->stack.ST[i].exp; sfpd.u.fields.sign = fpu->stack.ST[i].sign; sfpd.u.half = NXSwapShort(sfpd.u.half); memcpy(&(fpu->stack.ST[i]), &sfpd, sizeof(struct swapped_fp_data_reg)); } } }
void swap_i386_float_state( struct i386_float_state *fpu, enum NXByteOrder target_byte_sex) { #ifndef i386_EXCEPTION_STATE_COUNT /* this routine does nothing as their are currently no non-byte fields */ #else /* !defined(i386_EXCEPTION_STATE_COUNT) */ struct swapped_fp_control { union { struct { unsigned short :3, /*inf*/ :1, rc :2, pc :2, :2, precis :1, undfl :1, ovrfl :1, zdiv :1, denorm :1, invalid :1; } fields; unsigned short half; } u; } sfpc; struct swapped_fp_status { union { struct { unsigned short busy :1, c3 :1, tos :3, c2 :1, c1 :1, c0 :1, errsumm :1, stkflt :1, precis :1, undfl :1, ovrfl :1, zdiv :1, denorm :1, invalid :1; } fields; unsigned short half; } u; } sfps; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); fpu->fpu_reserved[0] = NXSwapLong(fpu->fpu_reserved[0]); fpu->fpu_reserved[1] = NXSwapLong(fpu->fpu_reserved[1]); if(target_byte_sex == host_byte_sex) { memcpy(&sfpc, &(fpu->fpu_fcw), sizeof(struct swapped_fp_control)); sfpc.u.half = NXSwapShort(sfpc.u.half); fpu->fpu_fcw.rc = sfpc.u.fields.rc; fpu->fpu_fcw.pc = sfpc.u.fields.pc; fpu->fpu_fcw.precis = sfpc.u.fields.precis; fpu->fpu_fcw.undfl = sfpc.u.fields.undfl; fpu->fpu_fcw.ovrfl = sfpc.u.fields.ovrfl; fpu->fpu_fcw.zdiv = sfpc.u.fields.zdiv; fpu->fpu_fcw.denorm = sfpc.u.fields.denorm; fpu->fpu_fcw.invalid = sfpc.u.fields.invalid; memcpy(&sfps, &(fpu->fpu_fsw), sizeof(struct swapped_fp_status)); sfps.u.half = NXSwapShort(sfps.u.half); fpu->fpu_fsw.busy = sfps.u.fields.busy; fpu->fpu_fsw.c3 = sfps.u.fields.c3; fpu->fpu_fsw.tos = sfps.u.fields.tos; fpu->fpu_fsw.c2 = sfps.u.fields.c2; fpu->fpu_fsw.c1 = sfps.u.fields.c1; fpu->fpu_fsw.c0 = sfps.u.fields.c0; fpu->fpu_fsw.errsumm = sfps.u.fields.errsumm; fpu->fpu_fsw.stkflt = sfps.u.fields.stkflt; fpu->fpu_fsw.precis = sfps.u.fields.precis; fpu->fpu_fsw.undfl = sfps.u.fields.undfl; fpu->fpu_fsw.ovrfl = sfps.u.fields.ovrfl; fpu->fpu_fsw.zdiv = sfps.u.fields.zdiv; fpu->fpu_fsw.denorm = sfps.u.fields.denorm; fpu->fpu_fsw.invalid = sfps.u.fields.invalid; } else { sfpc.u.fields.rc = fpu->fpu_fcw.rc; sfpc.u.fields.pc = fpu->fpu_fcw.pc; sfpc.u.fields.precis = fpu->fpu_fcw.precis; sfpc.u.fields.undfl = fpu->fpu_fcw.undfl; sfpc.u.fields.ovrfl = fpu->fpu_fcw.ovrfl; sfpc.u.fields.zdiv = fpu->fpu_fcw.zdiv; sfpc.u.fields.denorm = fpu->fpu_fcw.denorm; sfpc.u.fields.invalid = fpu->fpu_fcw.invalid; sfpc.u.half = NXSwapShort(sfpc.u.half); memcpy(&(fpu->fpu_fcw), &sfpc, sizeof(struct swapped_fp_control)); sfps.u.fields.busy = fpu->fpu_fsw.busy; sfps.u.fields.c3 = fpu->fpu_fsw.c3; sfps.u.fields.tos = fpu->fpu_fsw.tos; sfps.u.fields.c2 = fpu->fpu_fsw.c2; sfps.u.fields.c1 = fpu->fpu_fsw.c1; sfps.u.fields.c0 = fpu->fpu_fsw.c0; sfps.u.fields.errsumm = fpu->fpu_fsw.errsumm; sfps.u.fields.stkflt = fpu->fpu_fsw.stkflt; sfps.u.fields.precis = fpu->fpu_fsw.precis; sfps.u.fields.undfl = fpu->fpu_fsw.undfl; sfps.u.fields.ovrfl = fpu->fpu_fsw.ovrfl; sfps.u.fields.zdiv = fpu->fpu_fsw.zdiv; sfps.u.fields.denorm = fpu->fpu_fsw.denorm; sfps.u.fields.invalid = fpu->fpu_fsw.invalid; sfps.u.half = NXSwapShort(sfps.u.half); memcpy(&(fpu->fpu_fsw), &sfps, sizeof(struct swapped_fp_status)); } fpu->fpu_fop = NXSwapShort(fpu->fpu_fop); fpu->fpu_ip = NXSwapLong(fpu->fpu_ip); fpu->fpu_cs = NXSwapShort(fpu->fpu_cs); fpu->fpu_rsrv2 = NXSwapShort(fpu->fpu_rsrv2); fpu->fpu_dp = NXSwapLong(fpu->fpu_dp); fpu->fpu_ds = NXSwapShort(fpu->fpu_ds); fpu->fpu_rsrv3 = NXSwapShort(fpu->fpu_rsrv3); fpu->fpu_mxcsr = NXSwapLong(fpu->fpu_mxcsr); fpu->fpu_mxcsrmask = NXSwapLong(fpu->fpu_mxcsrmask); fpu->fpu_reserved1 = NXSwapLong(fpu->fpu_reserved1); #endif /* !defined(i386_EXCEPTION_STATE_COUNT) */ }
void swap_x86_float_state64( x86_float_state64_t *fpu, enum NXByteOrder target_byte_sex) { struct swapped_fp_control { union { struct { unsigned short :3, /*inf*/ :1, rc :2, pc :2, :2, precis :1, undfl :1, ovrfl :1, zdiv :1, denorm :1, invalid :1; } fields; unsigned short half; } u; } sfpc; struct swapped_fp_status { union { struct { unsigned short busy :1, c3 :1, tos :3, c2 :1, c1 :1, c0 :1, errsumm :1, stkflt :1, precis :1, undfl :1, ovrfl :1, zdiv :1, denorm :1, invalid :1; } fields; unsigned short half; } u; } sfps; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); fpu->fpu_reserved[0] = OSSwapInt32(fpu->fpu_reserved[0]); fpu->fpu_reserved[1] = OSSwapInt32(fpu->fpu_reserved[1]); if(target_byte_sex == host_byte_sex){ memcpy(&sfpc, &(fpu->fpu_fcw), sizeof(struct swapped_fp_control)); sfpc.u.half = OSSwapInt16(sfpc.u.half); fpu->fpu_fcw.rc = sfpc.u.fields.rc; fpu->fpu_fcw.pc = sfpc.u.fields.pc; fpu->fpu_fcw.precis = sfpc.u.fields.precis; fpu->fpu_fcw.undfl = sfpc.u.fields.undfl; fpu->fpu_fcw.ovrfl = sfpc.u.fields.ovrfl; fpu->fpu_fcw.zdiv = sfpc.u.fields.zdiv; fpu->fpu_fcw.denorm = sfpc.u.fields.denorm; fpu->fpu_fcw.invalid = sfpc.u.fields.invalid; memcpy(&sfps, &(fpu->fpu_fsw), sizeof(struct swapped_fp_status)); sfps.u.half = OSSwapInt16(sfps.u.half); fpu->fpu_fsw.busy = sfps.u.fields.busy; fpu->fpu_fsw.c3 = sfps.u.fields.c3; fpu->fpu_fsw.tos = sfps.u.fields.tos; fpu->fpu_fsw.c2 = sfps.u.fields.c2; fpu->fpu_fsw.c1 = sfps.u.fields.c1; fpu->fpu_fsw.c0 = sfps.u.fields.c0; fpu->fpu_fsw.errsumm = sfps.u.fields.errsumm; fpu->fpu_fsw.stkflt = sfps.u.fields.stkflt; fpu->fpu_fsw.precis = sfps.u.fields.precis; fpu->fpu_fsw.undfl = sfps.u.fields.undfl; fpu->fpu_fsw.ovrfl = sfps.u.fields.ovrfl; fpu->fpu_fsw.zdiv = sfps.u.fields.zdiv; fpu->fpu_fsw.denorm = sfps.u.fields.denorm; fpu->fpu_fsw.invalid = sfps.u.fields.invalid; } else{ sfpc.u.fields.rc = fpu->fpu_fcw.rc; sfpc.u.fields.pc = fpu->fpu_fcw.pc; sfpc.u.fields.precis = fpu->fpu_fcw.precis; sfpc.u.fields.undfl = fpu->fpu_fcw.undfl; sfpc.u.fields.ovrfl = fpu->fpu_fcw.ovrfl; sfpc.u.fields.zdiv = fpu->fpu_fcw.zdiv; sfpc.u.fields.denorm = fpu->fpu_fcw.denorm; sfpc.u.fields.invalid = fpu->fpu_fcw.invalid; sfpc.u.half = OSSwapInt16(sfpc.u.half); memcpy(&(fpu->fpu_fcw), &sfpc, sizeof(struct swapped_fp_control)); sfps.u.fields.busy = fpu->fpu_fsw.busy; sfps.u.fields.c3 = fpu->fpu_fsw.c3; sfps.u.fields.tos = fpu->fpu_fsw.tos; sfps.u.fields.c2 = fpu->fpu_fsw.c2; sfps.u.fields.c1 = fpu->fpu_fsw.c1; sfps.u.fields.c0 = fpu->fpu_fsw.c0; sfps.u.fields.errsumm = fpu->fpu_fsw.errsumm; sfps.u.fields.stkflt = fpu->fpu_fsw.stkflt; sfps.u.fields.precis = fpu->fpu_fsw.precis; sfps.u.fields.undfl = fpu->fpu_fsw.undfl; sfps.u.fields.ovrfl = fpu->fpu_fsw.ovrfl; sfps.u.fields.zdiv = fpu->fpu_fsw.zdiv; sfps.u.fields.denorm = fpu->fpu_fsw.denorm; sfps.u.fields.invalid = fpu->fpu_fsw.invalid; sfps.u.half = OSSwapInt16(sfps.u.half); memcpy(&(fpu->fpu_fsw), &sfps, sizeof(struct swapped_fp_status)); } fpu->fpu_fop = OSSwapInt16(fpu->fpu_fop); fpu->fpu_ip = OSSwapInt32(fpu->fpu_ip); fpu->fpu_cs = OSSwapInt16(fpu->fpu_cs); fpu->fpu_rsrv2 = OSSwapInt16(fpu->fpu_rsrv2); fpu->fpu_dp = OSSwapInt32(fpu->fpu_dp); fpu->fpu_ds = OSSwapInt16(fpu->fpu_ds); fpu->fpu_rsrv3 = OSSwapInt16(fpu->fpu_rsrv3); fpu->fpu_mxcsr = OSSwapInt32(fpu->fpu_mxcsr); fpu->fpu_mxcsrmask = OSSwapInt32(fpu->fpu_mxcsrmask); fpu->fpu_reserved1 = OSSwapInt32(fpu->fpu_reserved1); }
void swap_m88110_thread_state_impl_t( m88110_thread_state_impl_t *spu, enum NXByteOrder target_byte_sex) { uint32_t i; enum NXByteOrder host_byte_sex; struct swapped_m88110_bp_ctrl { union { struct { unsigned v:BIT_WIDTH(0); m88110_match_t addr_match:BITS_WIDTH(12,1); unsigned :BITS_WIDTH(26,13); unsigned rwm:BIT_WIDTH(27); unsigned rw:BIT_WIDTH(28); unsigned :BITS_WIDTH(31,29); } fields; uint32_t word; } u; } sbpc; struct swap_m88110_psr { union { struct { unsigned :BITS_WIDTH(1,0); unsigned mxm_dis:BIT_WIDTH(2); unsigned sfu1dis:BIT_WIDTH(3); unsigned :BITS_WIDTH(22,4); unsigned trace:BIT_WIDTH(23); unsigned :BIT_WIDTH(24); unsigned sm:BIT_WIDTH(25); unsigned sgn_imd:BIT_WIDTH(26); unsigned :BIT_WIDTH(27); unsigned c:BIT_WIDTH(28); unsigned se:BIT_WIDTH(29); unsigned le:BIT_WIDTH(30); unsigned supr:BIT_WIDTH(31); } fields; uint32_t word; } u; } spsr; struct swapped_m88110_fp_trap_status { union { struct { unsigned efinx:BIT_WIDTH(0); unsigned efovf:BIT_WIDTH(1); unsigned efunf:BIT_WIDTH(2); unsigned efdvz:BIT_WIDTH(3); unsigned efinv:BIT_WIDTH(4); unsigned priv:BIT_WIDTH(5); unsigned unimp:BIT_WIDTH(6); unsigned int:BIT_WIDTH(7); unsigned sfu1_disabled:BIT_WIDTH(8); unsigned :BITS_WIDTH(13,9); m88110_iresult_size_t iresult_size:BITS_WIDTH(15,14); unsigned :BITS_WIDTH(31,16); } fields; uint32_t word; } u; } sfps; host_byte_sex = NXHostByteOrder(); if(target_byte_sex == host_byte_sex){ for(i = 0; i < M88110_N_DATA_BP; i++){ spu->data_bp[i].addr = OSSwapInt32(spu->data_bp[i].addr); memcpy(&sbpc, &(spu->data_bp[i].ctrl), sizeof(struct swapped_m88110_bp_ctrl)); sbpc.u.word = OSSwapInt32(sbpc.u.word); spu->data_bp[i].ctrl.v = sbpc.u.fields.v; spu->data_bp[i].ctrl.addr_match = sbpc.u.fields.addr_match; spu->data_bp[i].ctrl.rwm = sbpc.u.fields.rwm; spu->data_bp[i].ctrl.rw = sbpc.u.fields.rw; } memcpy(&spsr, &(spu->psr), sizeof(struct swap_m88110_psr)); spsr.u.word = OSSwapInt32(spsr.u.word); spu->psr.mxm_dis = spsr.u.fields.mxm_dis; spu->psr.sfu1dis = spsr.u.fields.sfu1dis; spu->psr.trace = spsr.u.fields.trace; spu->psr.sm = spsr.u.fields.sm; spu->psr.sgn_imd = spsr.u.fields.sgn_imd; spu->psr.c = spsr.u.fields.c; spu->psr.se = spsr.u.fields.se; spu->psr.le = spsr.u.fields.le; spu->psr.supr = spsr.u.fields.supr; memcpy(&sfps, &(spu->fp_trap_status), sizeof(struct swapped_m88110_fp_trap_status)); sfps.u.word = OSSwapInt32(sfps.u.word); spu->fp_trap_status.efinx = sfps.u.fields.efinx; spu->fp_trap_status.efovf = sfps.u.fields.efovf; spu->fp_trap_status.efunf = sfps.u.fields.efunf; spu->fp_trap_status.efdvz = sfps.u.fields.efdvz; spu->fp_trap_status.efinv = sfps.u.fields.efinv; spu->fp_trap_status.priv = sfps.u.fields.priv; spu->fp_trap_status.unimp = sfps.u.fields.unimp; spu->fp_trap_status.sfu1_disabled = sfps.u.fields.sfu1_disabled; spu->fp_trap_status.iresult_size = sfps.u.fields.iresult_size; } else{ for(i = 0; i < M88110_N_DATA_BP; i++){ spu->data_bp[i].addr = OSSwapInt32(spu->data_bp[i].addr); sbpc.u.fields.v = spu->data_bp[i].ctrl.v; sbpc.u.fields.addr_match = spu->data_bp[i].ctrl.addr_match; sbpc.u.fields.rwm = spu->data_bp[i].ctrl.rwm; sbpc.u.fields.rw = spu->data_bp[i].ctrl.rw; sbpc.u.word = OSSwapInt32(sbpc.u.word); memcpy(&(spu->data_bp[i].ctrl), &sbpc, sizeof(struct swapped_m88110_bp_ctrl)); } spsr.u.fields.mxm_dis = spu->psr.mxm_dis; spsr.u.fields.sfu1dis = spu->psr.sfu1dis; spsr.u.fields.trace = spu->psr.trace; spsr.u.fields.sm = spu->psr.sm; spsr.u.fields.sgn_imd = spu->psr.sgn_imd; spsr.u.fields.c = spu->psr.c; spsr.u.fields.se = spu->psr.se; spsr.u.fields.le = spu->psr.le; spsr.u.fields.supr = spu->psr.supr; spsr.u.word = OSSwapInt32(spsr.u.word); memcpy(&(spu->psr), &spsr, sizeof(struct swap_m88110_psr)); sfps.u.fields.efinx = spu->fp_trap_status.efinx; sfps.u.fields.efovf = spu->fp_trap_status.efovf; sfps.u.fields.efunf = spu->fp_trap_status.efunf; sfps.u.fields.efdvz = spu->fp_trap_status.efdvz; sfps.u.fields.efinv = spu->fp_trap_status.efinv; sfps.u.fields.priv = spu->fp_trap_status.priv; sfps.u.fields.unimp = spu->fp_trap_status.unimp; sfps.u.fields.sfu1_disabled = spu->fp_trap_status.sfu1_disabled; sfps.u.fields.iresult_size = spu->fp_trap_status.iresult_size; sfps.u.word = OSSwapInt32(sfps.u.word); memcpy(&(spu->fp_trap_status), &sfps, sizeof(struct swapped_m88110_fp_trap_status)); } spu->intermediate_result.x[0] = OSSwapInt32(spu->intermediate_result.x[0]); spu->intermediate_result.x[1] = OSSwapInt32(spu->intermediate_result.x[1]); spu->intermediate_result.x[2] = OSSwapInt32(spu->intermediate_result.x[2]); spu->intermediate_result.x[3] = OSSwapInt32(spu->intermediate_result.x[3]); }
NXStream *NXGetStreamOnSection(const char *fileName, const char *segmentName, const char *sectionName) { int fd; struct stat info; NXStream *s = NULL; struct fat_header *fh; struct mach_header *mh; const struct section *sect; vm_offset_t mh_page, sect_page; unsigned long archOffset; unsigned int cnt = HOST_BASIC_INFO_COUNT; struct host_basic_info hbi; if (host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)(&hbi), &cnt) != KERN_SUCCESS) return NULL; fd = open(fileName, O_RDONLY, 0444); if (fd < 0 || fstat(fd, &info) < 0) return NULL; if (((info.st_mode & S_IFMT) != S_IFREG) || (info.st_size < sizeof(*fh))) { close(fd); return NULL; } if (map_fd(fd, 0, (vm_offset_t *)&fh, TRUE, (vm_size_t)info.st_size) != KERN_SUCCESS) { close(fd); return NULL; } #ifdef __BIG_ENDIAN__ if (fh->magic == FAT_MAGIC) { #endif __BIG_ENDIAN__ #ifdef __LITTLE_ENDIAN__ if (fh->magic == NXSwapLong(FAT_MAGIC)) { #endif __LITTLE_ENDIAN__ int i; struct fat_arch *fa = (struct fat_arch*)(fh + 1); #ifdef __LITTLE_ENDIAN__ enum NXByteOrder host_byte_sex = NXHostByteOrder(); swap_fat_header(fh, host_byte_sex); #endif __LITTLE_ENDIAN__ if ((fh->nfat_arch <= 0) || (info.st_size < sizeof(*fh)+sizeof(*fa)*fh->nfat_arch)) { vm_deallocate(mach_task_self(), (vm_offset_t)fh, info.st_size); close(fd); return NULL; } #ifdef __LITTLE_ENDIAN__ swap_fat_arch(fa, fh->nfat_arch, host_byte_sex); #endif __LITTLE_ENDIAN__ for (i = 0; i < fh->nfat_arch; i++, fa++) { if (fa->cputype == hbi.cpu_type) { //**** ** check for best cpu_subtype here ** (fa->cpusubtype == hbi.cpu_subtype) break; // for now, accept all subtypes } } if (i >= fh->nfat_arch) { vm_deallocate(mach_task_self(), (vm_offset_t)fh, info.st_size); close(fd); return NULL; } archOffset = fa->offset; mh = (struct mach_header*)((char*)fh + archOffset); } else { archOffset = 0L; mh = (struct mach_header*)fh; } if ((info.st_size < archOffset + sizeof(*mh)) || (mh->magic != MH_MAGIC) || (mh->cputype != hbi.cpu_type) || (info.st_size < archOffset + sizeof(*mh) + mh->sizeofcmds) || !check_wellformed_header(mh, info.st_size - archOffset, NO)) { // bug#21223 vm_deallocate(mach_task_self(), (vm_offset_t)fh, info.st_size); close(fd); return NULL; } /* * Get the section data. */ sect = getsectbynamefromheader(mh, segmentName, sectionName); if (sect == NULL || sect->size == 0 || (info.st_size < archOffset + sect->offset + sect->size)) { vm_deallocate(mach_task_self(), (vm_offset_t)fh, info.st_size); close(fd); return NULL; } /* * Create the stream. */ s = NXOpenMemory((char *)mh + sect->offset, sect->size, NX_READONLY); s->flags &= ~NX_USER_OWNS_BUF; /* * Through away the parts of the file not needed. Assert that all * pages that the file lives on are used only by the file. */ sect_page = round_page((vm_offset_t)mh + sect->offset + sect->size); mh_page = round_page((vm_offset_t)fh + info.st_size); if (mh_page - sect_page) vm_deallocate(mach_task_self(), sect_page, mh_page - sect_page); mh_page = trunc_page((vm_offset_t)fh); sect_page = trunc_page((vm_offset_t)mh + sect->offset); if (sect_page - mh_page) vm_deallocate(mach_task_self(), mh_page, sect_page - mh_page); if (close(fd) < 0) { NXCloseMemory(s, NX_FREEBUFFER); s = NULL; } return s; } NXStream *NXGetStreamOnSectionForBestArchitecture( const char *fileName, const char *segmentName, const char *sectionName) { int fd; struct stat info; NXStream *s = NULL; struct fat_header *fh; struct mach_header *mh; const struct section *sect; vm_offset_t mh_page, sect_page; unsigned long archOffset; unsigned int cnt = HOST_BASIC_INFO_COUNT; struct host_basic_info hbi; int fSwap = NO; if (host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)(&hbi), &cnt) != KERN_SUCCESS) return NULL; fd = open(fileName, O_RDONLY, 0444); if (fd < 0 || fstat(fd, &info) < 0) return NULL; if (((info.st_mode & S_IFMT) != S_IFREG) || (info.st_size < sizeof(*fh))) { close(fd); return NULL; } if (map_fd(fd, 0, (vm_offset_t *)&fh, TRUE, (vm_size_t)info.st_size) != KERN_SUCCESS) { close(fd); return NULL; } #ifdef __BIG_ENDIAN__ if (fh->magic == FAT_MAGIC) { #endif __BIG_ENDIAN__ #ifdef __LITTLE_ENDIAN__ if (fh->magic == NXSwapLong(FAT_MAGIC)) { #endif __LITTLE_ENDIAN__ int i; struct fat_arch *fa = (struct fat_arch*)(fh + 1); #ifdef __LITTLE_ENDIAN__ enum NXByteOrder host_byte_sex = NXHostByteOrder(); swap_fat_header(fh, host_byte_sex); #endif __LITTLE_ENDIAN__ if ((fh->nfat_arch <= 0) || (info.st_size < sizeof(*fh)+sizeof(*fa)*fh->nfat_arch)) { vm_deallocate(mach_task_self(), (vm_offset_t)fh, info.st_size); close(fd); return NULL; } #ifdef __LITTLE_ENDIAN__ swap_fat_arch(fa, fh->nfat_arch, host_byte_sex); #endif __LITTLE_ENDIAN__ for (i = 0; i < fh->nfat_arch; i++, fa++) { if (fa->cputype == hbi.cpu_type) { //**** ** check for best cpu_subtype here ** (fa->cpusubtype == hbi.cpu_subtype) break; // for now, accept all subtypes } } if (i >= fh->nfat_arch) { /* * If do not have the correct cpu_type, just use the last type * in file. * NOTE: we could have a list passed in, and choose the best * based upon that list. */ fa--; } archOffset = fa->offset; mh = (struct mach_header*)((char*)fh + archOffset); } else { archOffset = 0L; mh = (struct mach_header*)fh; } if (info.st_size < archOffset + sizeof(*mh)) { vm_deallocate(mach_task_self(), (vm_offset_t)fh, info.st_size); close(fd); return NULL; } /* * Do we need to swap the header? Header is always in byte-order of machine it * was compiled for. */ if (mh->magic == NXSwapLong(MH_MAGIC)) { fSwap = YES; #ifdef __LITTLE_ENDIAN__ swap_mach_header(mh, NX_LittleEndian); #else swap_mach_header(mh, NX_BigEndian); #endif __LITTLE_ENDIAN__ } if ((mh->magic != MH_MAGIC) || (info.st_size < archOffset + sizeof(*mh) + mh->sizeofcmds) || !check_wellformed_header(mh, info.st_size - archOffset, fSwap)) { // bug#21223 vm_deallocate(mach_task_self(), (vm_offset_t)fh, info.st_size); close(fd); return NULL; } /* * Get the section data. */ sect = getsectbynamefromheaderwithswap(mh, segmentName, sectionName, fSwap); if (sect == NULL || sect->size == 0 || (info.st_size < archOffset + sect->offset + sect->size)) { vm_deallocate(mach_task_self(), (vm_offset_t)fh, info.st_size); close(fd); return NULL; } /* * Create the stream. */ s = NXOpenMemory((char *)mh + sect->offset, sect->size, NX_READONLY); s->flags &= ~NX_USER_OWNS_BUF; /* * Through away the parts of the file not needed. Assert that all * pages that the file lives on are used only by the file. */ sect_page = round_page((vm_offset_t)mh + sect->offset + sect->size); mh_page = round_page((vm_offset_t)fh + info.st_size); if (mh_page - sect_page) vm_deallocate(mach_task_self(), sect_page, mh_page - sect_page); mh_page = trunc_page((vm_offset_t)fh); sect_page = trunc_page((vm_offset_t)mh + sect->offset); if (sect_page - mh_page) vm_deallocate(mach_task_self(), mh_page, sect_page - mh_page); if (close(fd) < 0) { NXCloseMemory(s, NX_FREEBUFFER); s = NULL; } return s; }
void swap_m88k_thread_state_xrf_t( m88k_thread_state_xrf_t *fpu, enum NXByteOrder target_byte_sex) { enum NXByteOrder host_byte_sex; struct swapped_m88k_fpsr { union { struct { unsigned afinx:BIT_WIDTH(0); unsigned afovf:BIT_WIDTH(1); unsigned afunf:BIT_WIDTH(2); unsigned afdvz:BIT_WIDTH(3); unsigned afinv:BIT_WIDTH(4); unsigned :BITS_WIDTH(15,5); unsigned xmod:BIT_WIDTH(16); unsigned :BITS_WIDTH(31,17); } fields; uint32_t word; } u; } ssr; struct swapped_m88k_fpcr { union { struct { unsigned efinx:BIT_WIDTH(0); unsigned efovf:BIT_WIDTH(1); unsigned efunf:BIT_WIDTH(2); unsigned efdvz:BIT_WIDTH(3); unsigned efinv:BIT_WIDTH(4); unsigned :BITS_WIDTH(13,5); m88k_fpcr_rm_t rm:BITS_WIDTH(15,14); unsigned :BITS_WIDTH(31,16); } fields; uint32_t word; } u; } scr; host_byte_sex = NXHostByteOrder(); fpu->x1.x[0] = OSSwapInt32(fpu->x1.x[0]); fpu->x1.x[1] = OSSwapInt32(fpu->x1.x[1]); fpu->x1.x[2] = OSSwapInt32(fpu->x1.x[2]); fpu->x1.x[3] = OSSwapInt32(fpu->x1.x[3]); fpu->x2.x[0] = OSSwapInt32(fpu->x2.x[0]); fpu->x2.x[1] = OSSwapInt32(fpu->x2.x[1]); fpu->x2.x[2] = OSSwapInt32(fpu->x2.x[2]); fpu->x2.x[3] = OSSwapInt32(fpu->x2.x[3]); fpu->x3.x[0] = OSSwapInt32(fpu->x3.x[0]); fpu->x3.x[1] = OSSwapInt32(fpu->x3.x[1]); fpu->x3.x[2] = OSSwapInt32(fpu->x3.x[2]); fpu->x3.x[3] = OSSwapInt32(fpu->x3.x[3]); fpu->x4.x[0] = OSSwapInt32(fpu->x4.x[0]); fpu->x4.x[1] = OSSwapInt32(fpu->x4.x[1]); fpu->x4.x[2] = OSSwapInt32(fpu->x4.x[2]); fpu->x4.x[3] = OSSwapInt32(fpu->x4.x[3]); fpu->x5.x[0] = OSSwapInt32(fpu->x5.x[0]); fpu->x5.x[1] = OSSwapInt32(fpu->x5.x[1]); fpu->x5.x[2] = OSSwapInt32(fpu->x5.x[2]); fpu->x5.x[3] = OSSwapInt32(fpu->x5.x[3]); fpu->x6.x[0] = OSSwapInt32(fpu->x6.x[0]); fpu->x6.x[1] = OSSwapInt32(fpu->x6.x[1]); fpu->x6.x[2] = OSSwapInt32(fpu->x6.x[2]); fpu->x6.x[3] = OSSwapInt32(fpu->x6.x[3]); fpu->x7.x[0] = OSSwapInt32(fpu->x7.x[0]); fpu->x7.x[1] = OSSwapInt32(fpu->x7.x[1]); fpu->x7.x[2] = OSSwapInt32(fpu->x7.x[2]); fpu->x7.x[3] = OSSwapInt32(fpu->x7.x[3]); fpu->x8.x[0] = OSSwapInt32(fpu->x8.x[0]); fpu->x8.x[1] = OSSwapInt32(fpu->x8.x[1]); fpu->x8.x[2] = OSSwapInt32(fpu->x8.x[2]); fpu->x8.x[3] = OSSwapInt32(fpu->x8.x[3]); fpu->x9.x[0] = OSSwapInt32(fpu->x9.x[0]); fpu->x9.x[1] = OSSwapInt32(fpu->x9.x[1]); fpu->x9.x[2] = OSSwapInt32(fpu->x9.x[2]); fpu->x9.x[3] = OSSwapInt32(fpu->x9.x[3]); fpu->x10.x[0] = OSSwapInt32(fpu->x10.x[0]); fpu->x10.x[1] = OSSwapInt32(fpu->x10.x[1]); fpu->x10.x[2] = OSSwapInt32(fpu->x10.x[2]); fpu->x10.x[3] = OSSwapInt32(fpu->x10.x[3]); fpu->x11.x[0] = OSSwapInt32(fpu->x11.x[0]); fpu->x11.x[1] = OSSwapInt32(fpu->x11.x[1]); fpu->x11.x[2] = OSSwapInt32(fpu->x11.x[2]); fpu->x11.x[3] = OSSwapInt32(fpu->x11.x[3]); fpu->x12.x[0] = OSSwapInt32(fpu->x12.x[0]); fpu->x12.x[1] = OSSwapInt32(fpu->x12.x[1]); fpu->x12.x[2] = OSSwapInt32(fpu->x12.x[2]); fpu->x12.x[3] = OSSwapInt32(fpu->x12.x[3]); fpu->x13.x[0] = OSSwapInt32(fpu->x13.x[0]); fpu->x13.x[1] = OSSwapInt32(fpu->x13.x[1]); fpu->x13.x[2] = OSSwapInt32(fpu->x13.x[2]); fpu->x13.x[3] = OSSwapInt32(fpu->x13.x[3]); fpu->x14.x[0] = OSSwapInt32(fpu->x14.x[0]); fpu->x14.x[1] = OSSwapInt32(fpu->x14.x[1]); fpu->x14.x[2] = OSSwapInt32(fpu->x14.x[2]); fpu->x14.x[3] = OSSwapInt32(fpu->x14.x[3]); fpu->x15.x[0] = OSSwapInt32(fpu->x15.x[0]); fpu->x15.x[1] = OSSwapInt32(fpu->x15.x[1]); fpu->x15.x[2] = OSSwapInt32(fpu->x15.x[2]); fpu->x15.x[3] = OSSwapInt32(fpu->x15.x[3]); fpu->x16.x[0] = OSSwapInt32(fpu->x16.x[0]); fpu->x16.x[1] = OSSwapInt32(fpu->x16.x[1]); fpu->x16.x[2] = OSSwapInt32(fpu->x16.x[2]); fpu->x16.x[3] = OSSwapInt32(fpu->x16.x[3]); fpu->x17.x[0] = OSSwapInt32(fpu->x17.x[0]); fpu->x17.x[1] = OSSwapInt32(fpu->x17.x[1]); fpu->x17.x[2] = OSSwapInt32(fpu->x17.x[2]); fpu->x17.x[3] = OSSwapInt32(fpu->x17.x[3]); fpu->x18.x[0] = OSSwapInt32(fpu->x18.x[0]); fpu->x18.x[1] = OSSwapInt32(fpu->x18.x[1]); fpu->x18.x[2] = OSSwapInt32(fpu->x18.x[2]); fpu->x18.x[3] = OSSwapInt32(fpu->x18.x[3]); fpu->x19.x[0] = OSSwapInt32(fpu->x19.x[0]); fpu->x19.x[1] = OSSwapInt32(fpu->x19.x[1]); fpu->x19.x[2] = OSSwapInt32(fpu->x19.x[2]); fpu->x19.x[3] = OSSwapInt32(fpu->x19.x[3]); fpu->x20.x[0] = OSSwapInt32(fpu->x20.x[0]); fpu->x20.x[1] = OSSwapInt32(fpu->x20.x[1]); fpu->x20.x[2] = OSSwapInt32(fpu->x20.x[2]); fpu->x20.x[3] = OSSwapInt32(fpu->x20.x[3]); fpu->x21.x[0] = OSSwapInt32(fpu->x21.x[0]); fpu->x21.x[1] = OSSwapInt32(fpu->x21.x[1]); fpu->x21.x[2] = OSSwapInt32(fpu->x21.x[2]); fpu->x21.x[3] = OSSwapInt32(fpu->x21.x[3]); fpu->x22.x[0] = OSSwapInt32(fpu->x22.x[0]); fpu->x22.x[1] = OSSwapInt32(fpu->x22.x[1]); fpu->x22.x[2] = OSSwapInt32(fpu->x22.x[2]); fpu->x22.x[3] = OSSwapInt32(fpu->x22.x[3]); fpu->x23.x[0] = OSSwapInt32(fpu->x23.x[0]); fpu->x23.x[1] = OSSwapInt32(fpu->x23.x[1]); fpu->x23.x[2] = OSSwapInt32(fpu->x23.x[2]); fpu->x23.x[3] = OSSwapInt32(fpu->x23.x[3]); fpu->x24.x[0] = OSSwapInt32(fpu->x24.x[0]); fpu->x24.x[1] = OSSwapInt32(fpu->x24.x[1]); fpu->x24.x[2] = OSSwapInt32(fpu->x24.x[2]); fpu->x24.x[3] = OSSwapInt32(fpu->x24.x[3]); fpu->x25.x[0] = OSSwapInt32(fpu->x25.x[0]); fpu->x25.x[1] = OSSwapInt32(fpu->x25.x[1]); fpu->x25.x[2] = OSSwapInt32(fpu->x25.x[2]); fpu->x25.x[3] = OSSwapInt32(fpu->x25.x[3]); fpu->x26.x[0] = OSSwapInt32(fpu->x26.x[0]); fpu->x26.x[1] = OSSwapInt32(fpu->x26.x[1]); fpu->x26.x[2] = OSSwapInt32(fpu->x26.x[2]); fpu->x26.x[3] = OSSwapInt32(fpu->x26.x[3]); fpu->x27.x[0] = OSSwapInt32(fpu->x27.x[0]); fpu->x27.x[1] = OSSwapInt32(fpu->x27.x[1]); fpu->x27.x[2] = OSSwapInt32(fpu->x27.x[2]); fpu->x27.x[3] = OSSwapInt32(fpu->x27.x[3]); fpu->x28.x[0] = OSSwapInt32(fpu->x28.x[0]); fpu->x28.x[1] = OSSwapInt32(fpu->x28.x[1]); fpu->x28.x[2] = OSSwapInt32(fpu->x28.x[2]); fpu->x28.x[3] = OSSwapInt32(fpu->x28.x[3]); fpu->x29.x[0] = OSSwapInt32(fpu->x29.x[0]); fpu->x29.x[1] = OSSwapInt32(fpu->x29.x[1]); fpu->x29.x[2] = OSSwapInt32(fpu->x29.x[2]); fpu->x29.x[3] = OSSwapInt32(fpu->x29.x[3]); fpu->x30.x[0] = OSSwapInt32(fpu->x30.x[0]); fpu->x30.x[1] = OSSwapInt32(fpu->x30.x[1]); fpu->x30.x[2] = OSSwapInt32(fpu->x30.x[2]); fpu->x30.x[3] = OSSwapInt32(fpu->x30.x[3]); fpu->x31.x[0] = OSSwapInt32(fpu->x31.x[0]); fpu->x31.x[1] = OSSwapInt32(fpu->x31.x[1]); fpu->x31.x[2] = OSSwapInt32(fpu->x31.x[2]); fpu->x31.x[3] = OSSwapInt32(fpu->x31.x[3]); if(target_byte_sex == host_byte_sex){ memcpy(&ssr, &(fpu->fpsr), sizeof(struct swapped_m88k_fpsr)); ssr.u.word = OSSwapInt32(ssr.u.word); fpu->fpsr.afinx = ssr.u.fields.afinx; fpu->fpsr.afovf = ssr.u.fields.afovf; fpu->fpsr.afunf = ssr.u.fields.afunf; fpu->fpsr.afdvz = ssr.u.fields.afdvz; fpu->fpsr.afinv = ssr.u.fields.afinv; fpu->fpsr.xmod = ssr.u.fields.xmod; memcpy(&scr, &(fpu->fpcr), sizeof(struct swapped_m88k_fpcr)); scr.u.word = OSSwapInt32(scr.u.word); fpu->fpcr.efinx = scr.u.fields.efinx; fpu->fpcr.efovf = scr.u.fields.efovf; fpu->fpcr.efunf = scr.u.fields.efunf; fpu->fpcr.efdvz = scr.u.fields.efdvz; fpu->fpcr.efinv = scr.u.fields.efinv; fpu->fpcr.rm = scr.u.fields.rm; } else{ ssr.u.fields.afinx = fpu->fpsr.afinx; ssr.u.fields.afovf = fpu->fpsr.afovf; ssr.u.fields.afunf = fpu->fpsr.afunf; ssr.u.fields.afdvz = fpu->fpsr.afdvz; ssr.u.fields.afinv = fpu->fpsr.afinv; ssr.u.fields.xmod = fpu->fpsr.xmod; ssr.u.word = OSSwapInt32(ssr.u.word); memcpy(&(fpu->fpsr), &ssr, sizeof(struct swapped_m88k_fpsr)); scr.u.fields.efinx = fpu->fpcr.efinx; scr.u.fields.efovf = fpu->fpcr.efovf; scr.u.fields.efunf = fpu->fpcr.efunf; scr.u.fields.efdvz = fpu->fpcr.efdvz; scr.u.fields.efinv = fpu->fpcr.efinv; scr.u.fields.rm = fpu->fpcr.rm; scr.u.word = OSSwapInt32(scr.u.word); memcpy(&(fpu->fpcr), &scr, sizeof(struct swapped_m88k_fpcr)); } }
void swap_i386_thread_exceptstate( i386_thread_exceptstate_t *exc, enum NXByteOrder target_byte_sex) { struct swapped_err_code { union { struct err_code_normal { unsigned int :16, index :13, tbl :2, ext :1; } normal; struct err_code_pgfault { unsigned int :29, user :1, wrtflt :1, prot :1; } pgfault; unsigned long word; } u; } sec; unsigned long word; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); exc->trapno = NXSwapLong(exc->trapno); if(exc->trapno == 14) { if(target_byte_sex == host_byte_sex) { memcpy(&sec, &(exc->err), sizeof(struct swapped_err_code)); sec.u.word = NXSwapLong(sec.u.word); exc->err.pgfault.user = sec.u.pgfault.user; exc->err.pgfault.wrtflt = sec.u.pgfault.wrtflt; exc->err.pgfault.prot = sec.u.pgfault.prot; } else { sec.u.pgfault.prot = exc->err.pgfault.prot; sec.u.pgfault.wrtflt = exc->err.pgfault.wrtflt; sec.u.pgfault.user = exc->err.pgfault.user; sec.u.word = NXSwapLong(sec.u.word); memcpy(&(exc->err), &sec, sizeof(struct swapped_err_code)); } } else { if(target_byte_sex == host_byte_sex) { memcpy(&sec, &(exc->err), sizeof(struct swapped_err_code)); sec.u.word = NXSwapLong(sec.u.word); word = sec.u.normal.index; exc->err.normal.index = NXSwapLong(word); exc->err.normal.tbl = sec.u.normal.tbl; exc->err.normal.ext = sec.u.normal.ext; } else { sec.u.normal.ext = exc->err.normal.ext; sec.u.normal.tbl = exc->err.normal.tbl; word = exc->err.normal.index; sec.u.normal.index = NXSwapLong(word); sec.u.word = NXSwapLong(sec.u.word); memcpy(&(exc->err), &sec, sizeof(struct swapped_err_code)); } } }
void swap_sparc_thread_state_fpu( struct sparc_thread_state_fpu *fpu, enum NXByteOrder target_byte_sex) { struct swapped_fsr { union { struct { unsigned int cexc:BITS_WIDTH(4,0), aexc:BITS_WIDTH(9,5), fcc:BITS_WIDTH(11,10), pr:BIT_WIDTH(12), qne:BIT_WIDTH(13), ftt:BITS_WIDTH(16,14), res:BITS_WIDTH(22,17), tem:BITS_WIDTH(27,23), rp:BITS_WIDTH(29,28), rd:BITS_WIDTH(31,30); } fields; unsigned int word; } u; } sfsr; unsigned long i; struct f_status *fpu_status; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); /* floating point registers */ for(i = 0; i < 16; i++) /* 16 doubles */ fpu->fpu.fpu_fr.Fpu_dregs[i] = NXSwapDouble(fpu->fpu.fpu_fr.Fpu_dregs[i]); fpu->fpu.Fpu_q[0].FQu.whole = NXSwapDouble(fpu->fpu.Fpu_q[0].FQu.whole); fpu->fpu.Fpu_q[1].FQu.whole = NXSwapDouble(fpu->fpu.Fpu_q[1].FQu.whole); fpu->fpu.Fpu_flags = NXSwapLong(fpu->fpu.Fpu_flags); fpu->fpu.Fpu_extra = NXSwapLong(fpu->fpu.Fpu_extra); fpu->fpu.Fpu_qcnt = NXSwapLong(fpu->fpu.Fpu_qcnt); fpu_status = (struct f_status *) &(fpu->fpu.Fpu_fsr); if(target_byte_sex == host_byte_sex){ memcpy(&sfsr, &(fpu->fpu.Fpu_fsr), sizeof(unsigned int)); sfsr.u.word = NXSwapLong(sfsr.u.word); fpu_status->FPUREG.Fpu_fsr_bits.rd = sfsr.u.fields.rd; fpu_status->FPUREG.Fpu_fsr_bits.rp = sfsr.u.fields.rp; fpu_status->FPUREG.Fpu_fsr_bits.tem = sfsr.u.fields.tem; fpu_status->FPUREG.Fpu_fsr_bits.res = sfsr.u.fields.res; fpu_status->FPUREG.Fpu_fsr_bits.ftt = sfsr.u.fields.ftt; fpu_status->FPUREG.Fpu_fsr_bits.qne = sfsr.u.fields.qne; fpu_status->FPUREG.Fpu_fsr_bits.pr = sfsr.u.fields.pr; fpu_status->FPUREG.Fpu_fsr_bits.fcc = sfsr.u.fields.fcc; fpu_status->FPUREG.Fpu_fsr_bits.aexc = sfsr.u.fields.aexc; fpu_status->FPUREG.Fpu_fsr_bits.cexc = sfsr.u.fields.cexc; } else{ sfsr.u.fields.rd = fpu_status->FPUREG.Fpu_fsr_bits.rd; sfsr.u.fields.rp = fpu_status->FPUREG.Fpu_fsr_bits.rp; sfsr.u.fields.tem = fpu_status->FPUREG.Fpu_fsr_bits.tem; sfsr.u.fields.res = fpu_status->FPUREG.Fpu_fsr_bits.res; sfsr.u.fields.ftt = fpu_status->FPUREG.Fpu_fsr_bits.ftt; sfsr.u.fields.qne = fpu_status->FPUREG.Fpu_fsr_bits.qne; sfsr.u.fields.pr = fpu_status->FPUREG.Fpu_fsr_bits.pr; sfsr.u.fields.fcc = fpu_status->FPUREG.Fpu_fsr_bits.fcc; sfsr.u.fields.aexc = fpu_status->FPUREG.Fpu_fsr_bits.aexc; sfsr.u.fields.cexc = fpu_status->FPUREG.Fpu_fsr_bits.cexc; sfsr.u.word = NXSwapLong(sfsr.u.word); memcpy(&(fpu->fpu.Fpu_fsr), &sfsr, sizeof(struct swapped_fsr)); } }
void swap_sparc_thread_state_regs( struct sparc_thread_state_regs *cpu, enum NXByteOrder target_byte_sex) { struct swapped_psr { union { struct { unsigned int cwp:BITS_WIDTH(4,0), et:BIT_WIDTH(5), ps:BIT_WIDTH(6), s:BIT_WIDTH(7), pil:BITS_WIDTH(11,8), ef:BIT_WIDTH(12), ec:BIT_WIDTH(13), reserved:BITS_WIDTH(19,14), icc:BITS_WIDTH(23,20), ver:BITS_WIDTH(27,24), impl:BITS_WIDTH(31,28); } fields; unsigned int word; } u; } spsr; struct p_status *pr_status; enum NXByteOrder host_byte_sex; host_byte_sex = NXHostByteOrder(); cpu->regs.r_pc = NXSwapLong(cpu->regs.r_pc); cpu->regs.r_npc = NXSwapLong(cpu->regs.r_npc); cpu->regs.r_y = NXSwapLong(cpu->regs.r_y); cpu->regs.r_g1 = NXSwapLong(cpu->regs.r_g1); cpu->regs.r_g2 = NXSwapLong(cpu->regs.r_g2); cpu->regs.r_g3 = NXSwapLong(cpu->regs.r_g3); cpu->regs.r_g4 = NXSwapLong(cpu->regs.r_g4); cpu->regs.r_g5 = NXSwapLong(cpu->regs.r_g5); cpu->regs.r_g6 = NXSwapLong(cpu->regs.r_g6); cpu->regs.r_g7 = NXSwapLong(cpu->regs.r_g7); cpu->regs.r_o0 = NXSwapLong(cpu->regs.r_o0); cpu->regs.r_o1 = NXSwapLong(cpu->regs.r_o1); cpu->regs.r_o2 = NXSwapLong(cpu->regs.r_o2); cpu->regs.r_o3 = NXSwapLong(cpu->regs.r_o3); cpu->regs.r_o4 = NXSwapLong(cpu->regs.r_o4); cpu->regs.r_o5 = NXSwapLong(cpu->regs.r_o5); cpu->regs.r_o6 = NXSwapLong(cpu->regs.r_o6); cpu->regs.r_o7 = NXSwapLong(cpu->regs.r_o7); pr_status = (struct p_status *) &(cpu->regs.r_psr); if(target_byte_sex == host_byte_sex){ memcpy(&spsr, &(cpu->regs.r_psr), sizeof(struct swapped_psr)); spsr.u.word = NXSwapLong(spsr.u.word); pr_status->PSRREG.psr_bits.cwp = spsr.u.fields.cwp; pr_status->PSRREG.psr_bits.ps = spsr.u.fields.ps; pr_status->PSRREG.psr_bits.s = spsr.u.fields.s; pr_status->PSRREG.psr_bits.pil = spsr.u.fields.pil; pr_status->PSRREG.psr_bits.ef = spsr.u.fields.ef; pr_status->PSRREG.psr_bits.ec = spsr.u.fields.ec; pr_status->PSRREG.psr_bits.reserved = spsr.u.fields.reserved; pr_status->PSRREG.psr_bits.icc = spsr.u.fields.icc; pr_status->PSRREG.psr_bits.et = spsr.u.fields.ver; pr_status->PSRREG.psr_bits.impl = spsr.u.fields.impl; } else{ spsr.u.fields.cwp = pr_status->PSRREG.psr_bits.cwp; spsr.u.fields.ps = pr_status->PSRREG.psr_bits.ps; spsr.u.fields.s = pr_status->PSRREG.psr_bits.s; spsr.u.fields.pil = pr_status->PSRREG.psr_bits.pil; spsr.u.fields.ef = pr_status->PSRREG.psr_bits.ef; spsr.u.fields.ec = pr_status->PSRREG.psr_bits.ec; spsr.u.fields.reserved = pr_status->PSRREG.psr_bits.reserved; spsr.u.fields.icc = pr_status->PSRREG.psr_bits.icc; spsr.u.fields.ver = pr_status->PSRREG.psr_bits.et; spsr.u.fields.impl = pr_status->PSRREG.psr_bits.impl; spsr.u.word = NXSwapLong(spsr.u.word); memcpy(&(cpu->regs.r_psr), &spsr, sizeof(struct swapped_psr)); } }
void swap_relocation_info( struct relocation_info *relocs, uint32_t nrelocs, enum NXByteOrder target_byte_sex) { uint32_t i; enum NXByteOrder host_byte_sex; uint32_t to_host_byte_sex, scattered; struct swapped_relocation_info { uint32_t r_address; union { struct { unsigned int r_type:4, r_extern:1, r_length:2, r_pcrel:1, r_symbolnum:24; } fields; uint32_t word; } u; } sr; struct swapped_scattered_relocation_info { uint32_t word; uint32_t r_value; } *ssr; host_byte_sex = NXHostByteOrder(); to_host_byte_sex = target_byte_sex == host_byte_sex; for(i = 0; i < nrelocs; i++){ if(to_host_byte_sex) scattered = (OSSwapInt32(relocs[i].r_address) & R_SCATTERED) != 0; else scattered = ((relocs[i].r_address) & R_SCATTERED) != 0; if(scattered == FALSE){ if(to_host_byte_sex){ memcpy(&sr, relocs + i, sizeof(struct relocation_info)); sr.r_address = OSSwapInt32(sr.r_address); sr.u.word = OSSwapInt32(sr.u.word); relocs[i].r_address = sr.r_address; relocs[i].r_symbolnum = sr.u.fields.r_symbolnum; relocs[i].r_pcrel = sr.u.fields.r_pcrel; relocs[i].r_length = sr.u.fields.r_length; relocs[i].r_extern = sr.u.fields.r_extern; relocs[i].r_type = sr.u.fields.r_type; } else{ sr.r_address = relocs[i].r_address; sr.u.fields.r_symbolnum = relocs[i].r_symbolnum; sr.u.fields.r_length = relocs[i].r_length; sr.u.fields.r_pcrel = relocs[i].r_pcrel; sr.u.fields.r_extern = relocs[i].r_extern; sr.u.fields.r_type = relocs[i].r_type; sr.r_address = OSSwapInt32(sr.r_address); sr.u.word = OSSwapInt32(sr.u.word); memcpy(relocs + i, &sr, sizeof(struct relocation_info)); } } else{ ssr = (struct swapped_scattered_relocation_info *)(relocs + i); ssr->word = OSSwapInt32(ssr->word); ssr->r_value = OSSwapInt32(ssr->r_value); } } }
static int register_mach_header(const char* build, const char* project, const char* path, struct fat_arch* fa, int fd, int* isMachO) { ssize_t res; uint32_t magic; int swap = 0; struct mach_header* mh = NULL; struct mach_header_64* mh64 = NULL; if (isMachO) *isMachO = 0; res = read(fd, &magic, sizeof(uint32_t)); if (res < sizeof(uint32_t)) { return 0; } // // 32-bit, read the rest of the header // if (magic == MH_MAGIC || magic == MH_CIGAM) { if (isMachO) *isMachO = 1; mh = malloc(sizeof(struct mach_header)); if (mh == NULL) return -1; memset(mh, 0, sizeof(struct mach_header)); mh->magic = magic; res = read(fd, &mh->cputype, sizeof(struct mach_header) - sizeof(uint32_t)); if (res < sizeof(struct mach_header) - sizeof(uint32_t)) { return 0; } if (magic == MH_CIGAM) { swap = 1; swap_mach_header(mh, NXHostByteOrder()); } // // 64-bit, read the rest of the header // } else if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64) { if (isMachO) *isMachO = 1; mh64 = malloc(sizeof(struct mach_header_64)); if (mh64 == NULL) return -1; memset(mh64, 0, sizeof(struct mach_header_64)); mh64->magic = magic; res = read(fd, &mh64->cputype, sizeof(struct mach_header_64) - sizeof(uint32_t)); if (res < sizeof(struct mach_header_64) - sizeof(uint32_t)) { return 0; } if (magic == MH_CIGAM_64) { swap = 1; swap_mach_header_64(mh64, NXHostByteOrder()); } // // Not a Mach-O // } else { return 0; } switch (mh64 ? mh64->filetype : mh->filetype) { case MH_EXECUTE: case MH_DYLIB: case MH_BUNDLE: break; case MH_OBJECT: default: return 0; } res = SQL("INSERT INTO mach_o_objects (magic, type, cputype, cpusubtype, flags, build, project, path) VALUES (%u, %u, %u, %u, %u, %Q, %Q, %Q)", mh64 ? mh64->magic : mh->magic, mh64 ? mh64->filetype : mh->filetype, mh64 ? mh64->cputype : mh->cputype, mh64 ? mh64->cpusubtype : mh->cpusubtype, mh64 ? mh64->flags : mh->flags, build, project, path); uint64_t serial = sqlite3_last_insert_rowid((sqlite3*)_DBPluginGetDataStorePtr()); // // Information needed to parse the symbol table // int count_nsect = 0; unsigned char text_nsect = NO_SECT; unsigned char data_nsect = NO_SECT; unsigned char bss_nsect = NO_SECT; uint32_t nsyms = 0; uint8_t *symbols = NULL; uint32_t strsize = 0; uint8_t *strings = NULL; int i; uint32_t ncmds = mh64 ? mh64->ncmds : mh->ncmds; for (i = 0; i < ncmds; ++i) { // // Read a generic load command into memory. // At first, we only know it has a type and size. // struct load_command lctmp; ssize_t res = read(fd, &lctmp, sizeof(struct load_command)); if (res < sizeof(struct load_command)) { return 0; } uint32_t cmd = swap ? OSSwapInt32(lctmp.cmd) : lctmp.cmd; uint32_t cmdsize = swap ? OSSwapInt32(lctmp.cmdsize) : lctmp.cmdsize; if (cmdsize == 0) continue; struct load_command* lc = malloc(cmdsize); if (lc == NULL) { return 0; } memset(lc, 0, cmdsize); memcpy(lc, &lctmp, sizeof(lctmp)); // Read the remainder of the load command. res = read(fd, (uint8_t*)lc + sizeof(struct load_command), cmdsize - sizeof(struct load_command)); if (res < (cmdsize - sizeof(struct load_command))) { free(lc); return 0; } // // LC_LOAD_DYLIB and LC_LOAD_WEAK_DYLIB // Add dylibs as unresolved "lib" dependencies. // if (cmd == LC_LOAD_DYLIB || cmd == LC_LOAD_WEAK_DYLIB) { struct dylib_command *dylib = (struct dylib_command*)lc; if (swap) swap_dylib_command(dylib, NXHostByteOrder()); // sections immediately follow the dylib_command structure, and are // reflected in the cmdsize. int strsize = dylib->cmdsize - sizeof(struct dylib_command); char* str = malloc(strsize+1); strncpy(str, (char*)((uint8_t*)dylib + dylib->dylib.name.offset), strsize); str[strsize] = 0; // NUL-terminate res = SQL("INSERT INTO unresolved_dependencies (build,project,type,dependency) VALUES (%Q,%Q,%Q,%Q)", build, project, "lib", str); free(str); // // LC_LOAD_DYLINKER // Add the dynamic linker (usually dyld) as an unresolved "lib" dependency. // } else if (cmd == LC_LOAD_DYLINKER) { struct dylinker_command *dylinker = (struct dylinker_command*)lc; if (swap) swap_dylinker_command(dylinker, NXHostByteOrder()); // sections immediately follow the dylib_command structure, and are // reflected in the cmdsize. int strsize = dylinker->cmdsize - sizeof(struct dylinker_command); char* str = malloc(strsize+1); strncpy(str, (char*)((uint8_t*)dylinker + dylinker->name.offset), strsize); str[strsize] = 0; // NUL-terminate res = SQL("INSERT INTO unresolved_dependencies (build,project,type,dependency) VALUES (%Q,%Q,%Q,%Q)", build, project, "lib", str); free(str); // // LC_SYMTAB // Read the symbol table into memory, we'll process it after we're // done with the load commands. // } else if (cmd == LC_SYMTAB && symbols == NULL) { struct symtab_command *symtab = (struct symtab_command*)lc; if (swap) swap_symtab_command(symtab, NXHostByteOrder()); nsyms = symtab->nsyms; uint32_t symsize = nsyms * (mh64 ? sizeof(struct nlist_64) : sizeof(struct nlist)); symbols = malloc(symsize); strsize = symtab->strsize; // XXX: check strsize != 0 strings = malloc(strsize); off_t save = lseek(fd, 0, SEEK_CUR); off_t origin = fa ? fa->offset : 0; lseek(fd, (off_t)symtab->symoff + origin, SEEK_SET); res = read(fd, symbols, symsize); if (res < symsize) { /* XXX: leaks */ return 0; } lseek(fd, (off_t)symtab->stroff + origin, SEEK_SET); res = read(fd, strings, strsize); if (res < strsize) { /* XXX: leaks */ return 0; } lseek(fd, save, SEEK_SET); // // LC_SEGMENT // We're looking for the section number of the text, data, and bss segments // in order to parse symbols. // } else if (cmd == LC_SEGMENT) { struct segment_command* seg = (struct segment_command*)lc; if (swap) swap_segment_command(seg, NXHostByteOrder()); // sections immediately follow the segment_command structure, and are // reflected in the cmdsize. int k; for (k = 0; k < seg->nsects; ++k) { struct section* sect = (struct section*)((uint8_t*)seg + sizeof(struct segment_command) + k * sizeof(struct section)); if (swap) swap_section(sect, 1, NXHostByteOrder()); if (strcmp(sect->sectname, SECT_TEXT) == 0 && strcmp(sect->segname, SEG_TEXT) == 0) { text_nsect = ++count_nsect; } else if (strcmp(sect->sectname, SECT_DATA) == 0 && strcmp(sect->segname, SEG_DATA) == 0) { data_nsect = ++count_nsect; } else if (strcmp(sect->sectname, SECT_BSS) == 0 && strcmp(sect->segname, SEG_DATA) == 0) { bss_nsect = ++count_nsect; } else { ++count_nsect; } } // // LC_SEGMENT_64 // Same as LC_SEGMENT, but for 64-bit binaries. // } else if (lc->cmd == LC_SEGMENT_64) { struct segment_command_64* seg = (struct segment_command_64*)lc; if (swap) swap_segment_command_64(seg, NXHostByteOrder()); // sections immediately follow the segment_command structure, and are // reflected in the cmdsize. int k; for (k = 0; k < seg->nsects; ++k) { struct section_64* sect = (struct section_64*)((uint8_t*)seg + sizeof(struct segment_command_64) + k * sizeof(struct section_64)); if (swap) swap_section_64(sect, 1, NXHostByteOrder()); if (strcmp(sect->sectname, SECT_TEXT) == 0 && strcmp(sect->segname, SEG_TEXT) == 0) { text_nsect = ++count_nsect; } else if (strcmp(sect->sectname, SECT_DATA) == 0 && strcmp(sect->segname, SEG_DATA) == 0) { data_nsect = ++count_nsect; } else if (strcmp(sect->sectname, SECT_BSS) == 0 && strcmp(sect->segname, SEG_DATA) == 0) { bss_nsect = ++count_nsect; } else { ++count_nsect; } } } free(lc); } // // Finished processing the load commands, now insert symbols into the database. // int j; for (j = 0; j < nsyms; ++j) { struct nlist_64 symbol; if (mh64) { memcpy(&symbol, (symbols + j * sizeof(struct nlist_64)), sizeof(struct nlist_64)); if (swap) swap_nlist_64(&symbol, 1, NXHostByteOrder()); } else { symbol.n_value = 0; memcpy(&symbol, (symbols + j * sizeof(struct nlist)), sizeof(struct nlist)); if (swap) swap_nlist_64(&symbol, 1, NXHostByteOrder()); // we copied a 32-bit nlist into a 64-bit one, adjust the value accordingly // all other fields are identical sizes symbol.n_value >>= 32; } char type = '?'; switch (symbol.n_type & N_TYPE) { case N_UNDF: case N_PBUD: type = 'u'; if (symbol.n_value != 0) { type = 'c'; } break; case N_ABS: type = 'a'; break; case N_SECT: if (symbol.n_sect == text_nsect) { type = 't'; } else if (symbol.n_sect == data_nsect) { type = 'd'; } else if (symbol.n_sect == bss_nsect) { type = 'b'; } else { type = 's'; } break; case N_INDR: type = 'i'; break; } // uppercase indicates an externally visible symbol if ((symbol.n_type & N_EXT) && type != '?') { type = toupper(type); } if (type != '?' && type != 'u' && type != 'c') { const uint8_t* name = (const uint8_t*)""; if (symbol.n_un.n_strx != 0) { name = (uint8_t*)(strings + symbol.n_un.n_strx); } res = SQL("INSERT INTO mach_o_symbols VALUES (%lld, \'%c\', %lld, %Q)", serial, type, symbol.n_value, name); } } return 0; }