void read_chunk_tls(void *fptr, int action) { struct user_desc u; int ret; read_bit(fptr, &u, sizeof(struct user_desc)); if (!u.base_addr) return; if (action & ACTION_PRINT) fprintf(stderr, "TLS entry (%d): base_addr = 0x%lx", u.entry_number, u.base_addr); if (!(action & ACTION_LOAD)) return; if (!emulate_tls) { ret = set_thread_area(NULL); if (ret == -1) /* some libcs return the actual errno instead of -1 */ ret = -errno; if (ret == -ENOSYS) { /* We are not a TLS capable system. Turn on TLS emulation voodoo. */ emulate_tls = 1; /* We'll need write access to the code segments to do this. */ extra_prot_flags |= PROT_WRITE; } } if (emulate_tls) tls_base_address = u.base_addr; else syscall_check(set_thread_area(&u), 0, "set_thread_area"); }
bool CFile::Flush() { MULE_VALIDATE_STATE(IsOpened(), wxT("CFile: Cannot flush closed file.")); bool flushed = (FLUSH_FD(m_fd) != -1); syscall_check(flushed, m_filePath, wxT("flushing file")); return flushed; }
void install_tls_segv_handler() { struct k_sigaction sa; struct k_sigaction old_sa; memset(&sa, 0, sizeof(sa)); sa.sa_hand = (__sighandler_t)tls_segv_handler; sa.sa_flags = SA_SIGINFO; syscall_check(rt_sigaction(SIGSEGV, &sa, &old_sa, sizeof(arch_sigset_t)), 0, "set_rt_sigaction"); }
static void lzo_writer_dup2(void *fptr, int newfd) { struct lzo_data *ld = fptr; if (newfd == ld->fd) return; syscall_check(dup2(ld->fd, newfd), 0, "lzo_dup2(%d, %d)", ld->fd, newfd); close(ld->fd); ld->fd = newfd; }
static void gzip_writer_dup2(void *fptr, int newfd) { struct gzip_data *zd = fptr; if (newfd == zd->fd) return; syscall_check(dup2(zd->fd, newfd), 0, "gzip_dup2(%d, %d)", zd->fd, newfd); close(zd->fd); zd->fd = newfd; }
bool CFile::Close() { MULE_VALIDATE_STATE(IsOpened(), wxT("CFile: Cannot close closed file.")); bool closed = (close(m_fd) != -1); syscall_check(closed, m_filePath, wxT("closing file")); m_fd = fd_invalid; if (m_safeWrite) { CPath filePathTemp(m_filePath); m_filePath = m_filePath.RemoveExt(); // restore m_filePath for Reopen() if (closed) { closed = CPath::RenameFile(filePathTemp, m_filePath, true); } } return closed; }
bool CFile::SetLength(uint64 new_len) { MULE_VALIDATE_STATE(IsOpened(), wxT("CFile: Cannot set length when no file is open.")); #ifdef __WINDOWS__ #ifdef _MSC_VER // MSVC has a 64bit version bool result = _chsize_s(m_fd, new_len) == 0; #else // MingW has an old runtime without it bool result = chsize(m_fd, new_len) == 0; #endif #else bool result = ftruncate(m_fd, new_len) != -1; #endif syscall_check(result, m_filePath, wxT("truncating file")); return result; }
bool CFile::Open(const CPath& fileName, OpenMode mode, int accessMode) { MULE_VALIDATE_PARAMS(fileName.IsOk(), wxT("CFile: Cannot open, empty path.")); if (IsOpened()) { Close(); } m_safeWrite = false; m_filePath = fileName; #ifdef __linux__ int flags = O_BINARY | O_LARGEFILE; #else int flags = O_BINARY; #endif switch ( mode ) { case read: flags |= O_RDONLY; break; case write_append: if (fileName.FileExists()) { flags |= O_WRONLY | O_APPEND; break; } //else: fall through as write_append is the same as write if the // file doesn't exist case write: flags |= O_WRONLY | O_CREAT | O_TRUNC; break; case write_safe: flags |= O_WRONLY | O_CREAT | O_TRUNC; m_filePath = m_filePath.AppendExt(wxT(".new")); m_safeWrite = true; break; case write_excl: flags |= O_WRONLY | O_CREAT | O_EXCL; break; case read_write: flags |= O_RDWR; break; } // Windows needs wide character file names #ifdef __WINDOWS__ m_fd = _wopen(m_filePath.GetRaw().c_str(), flags, accessMode); #else Unicode2CharBuf tmpFileName = filename2char(m_filePath.GetRaw()); wxASSERT_MSG(tmpFileName, wxT("Convertion failed in CFile::Open")); m_fd = open(tmpFileName, flags, accessMode); #endif syscall_check(m_fd != fd_invalid, m_filePath, wxT("opening file")); return IsOpened(); }
void seek_to_image(int fd) { Elf64_Ehdr e; Elf64_Shdr s; int i; char* strtab; syscall_check(lseek(fd, 0, SEEK_SET), 0, "lseek"); safe_read(fd, &e, sizeof(e), "Elf64_Ehdr"); if (e.e_shoff == 0) { fprintf(stderr, "No section header found in self! Bugger.\n"); exit(1); } if (e.e_shentsize != sizeof(Elf64_Shdr)) { fprintf(stderr, "Section headers incorrect size. Bugger.\n"); exit(1); } if (e.e_shstrndx == SHN_UNDEF) { fprintf(stderr, "String section missing. Bugger.\n"); exit(1); } /* read the string table */ syscall_check(lseek(fd, e.e_shoff+(e.e_shstrndx*sizeof(Elf64_Shdr)), SEEK_SET), 0, "lseek"); safe_read(fd, &s, sizeof(s), "string table section header"); syscall_check(lseek(fd, s.sh_offset, SEEK_SET), 0, "lseek"); strtab = xmalloc(s.sh_size); safe_read(fd, strtab, s.sh_size, "string table"); for (i=0; i < e.e_shnum; i++) { long offset; syscall_check( lseek(fd, e.e_shoff+(i*sizeof(Elf64_Shdr)), SEEK_SET), 0, "lseek"); safe_read(fd, &s, sizeof(s), "Elf64_Shdr"); if (s.sh_type != SHT_PROGBITS || s.sh_name == 0) continue; /* We have potential data! Is it really ours? */ if (memcmp(strtab+s.sh_name, "cryopid.image", 13) != 0) continue; if (s.sh_info != IMAGE_VERSION) { fprintf(stderr, "Incorrect image version found (%d)! Keeping on trying.\n", s.sh_info); continue; } /* Woo! got it! */ syscall_check( lseek(fd, s.sh_offset, SEEK_SET), 0, "lseek"); safe_read(fd, &offset, sizeof(offset), "offset"); syscall_check( lseek(fd, offset, SEEK_SET), 0, "lseek"); return; } fprintf(stderr, "Program image not found!\n"); exit(1); }
/** * main */ int main(int argc, char *argv[]) { int i_x86 = 0; int i_x86_64 = 0; int i_x32 = 0; int i_arm = 0; int i_aarch64 = 0; int i_mips = 0; int i_mips64 = 0; int i_mips64n32 = 0; int i_parisc = 0; int i_ppc = 0; int i_ppc64 = 0; int i_s390 = 0; int i_s390x = 0; const char *sys_name; char str_miss[256]; do { str_miss[0] = '\0'; sys_name = x86_syscall_iterate_name(i_x86); if (sys_name == NULL) { printf("FAULT\n"); return 1; } /* check each arch using x86 as the reference */ syscall_check(str_miss, sys_name, "x86_64", x86_64_syscall_iterate_name(i_x86_64)); syscall_check(str_miss, sys_name, "x32", x32_syscall_iterate_name(i_x32)); syscall_check(str_miss, sys_name, "arm", arm_syscall_iterate_name(i_arm)); syscall_check(str_miss, sys_name, "aarch64", aarch64_syscall_iterate_name(i_aarch64)); syscall_check(str_miss, sys_name, "mips", mips_syscall_iterate_name(i_mips)); syscall_check(str_miss, sys_name, "mips64", mips64_syscall_iterate_name(i_mips64)); syscall_check(str_miss, sys_name, "mips64n32", mips64n32_syscall_iterate_name(i_mips64n32)); syscall_check(str_miss, sys_name, "parisc", parisc_syscall_iterate_name(i_parisc)); syscall_check(str_miss, sys_name, "ppc", ppc_syscall_iterate_name(i_ppc)); syscall_check(str_miss, sys_name, "ppc64", ppc64_syscall_iterate_name(i_ppc64)); syscall_check(str_miss, sys_name, "s390", s390_syscall_iterate_name(i_s390)); syscall_check(str_miss, sys_name, "s390x", s390x_syscall_iterate_name(i_s390x)); /* output the results */ printf("%s: ", sys_name); if (str_miss[0] != '\0') { printf("MISS(%s)\n", str_miss); return 1; } else printf("OK\n"); /* next */ if (x86_syscall_iterate_name(i_x86 + 1)) i_x86++; if (!x86_64_syscall_iterate_name(++i_x86_64)) i_x86_64 = -1; if (!x32_syscall_iterate_name(++i_x32)) i_x32 = -1; if (!arm_syscall_iterate_name(++i_arm)) i_arm = -1; if (!aarch64_syscall_iterate_name(++i_aarch64)) i_aarch64 = -1; if (!mips_syscall_iterate_name(++i_mips)) i_mips = -1; if (!mips64_syscall_iterate_name(++i_mips64)) i_mips64 = -1; if (!mips64n32_syscall_iterate_name(++i_mips64n32)) i_mips64n32 = -1; if (!parisc_syscall_iterate_name(++i_parisc)) i_parisc = -1; if (!ppc_syscall_iterate_name(++i_ppc)) i_ppc = -1; if (!ppc64_syscall_iterate_name(++i_ppc64)) i_ppc64 = -1; if (!s390_syscall_iterate_name(++i_s390)) i_s390 = -1; if (!s390x_syscall_iterate_name(++i_s390x)) i_s390x = -1; } while (i_x86_64 >= 0 && i_x32 >= 0 && i_arm >= 0 && i_aarch64 >= 0 && i_mips >= 0 && i_mips64 >= 0 && i_mips64n32 >= 0 && i_parisc >= 0 && i_ppc >= 0 && i_ppc64 >= 0 && i_s390 >= 0 && i_s390x >= 0); /* check for any leftovers */ sys_name = x86_syscall_iterate_name(i_x86 + 1); if (sys_name) { printf("%s: ERROR, x86 has additional syscalls\n", sys_name); return 1; } if (i_x86_64 >= 0) { printf("%s: ERROR, x86_64 has additional syscalls\n", x86_64_syscall_iterate_name(i_x86_64)); return 1; } if (i_x32 >= 0) { printf("%s: ERROR, x32 has additional syscalls\n", x32_syscall_iterate_name(i_x32)); return 1; } if (i_arm >= 0) { printf("%s: ERROR, arm has additional syscalls\n", arm_syscall_iterate_name(i_arm)); return 1; } if (i_aarch64 >= 0) { printf("%s: ERROR, aarch64 has additional syscalls\n", aarch64_syscall_iterate_name(i_aarch64)); return 1; } if (i_mips >= 0) { printf("%s: ERROR, mips has additional syscalls\n", mips_syscall_iterate_name(i_mips)); return 1; } if (i_mips64 >= 0) { printf("%s: ERROR, mips64 has additional syscalls\n", mips64_syscall_iterate_name(i_mips64)); return 1; } if (i_mips64n32 >= 0) { printf("%s: ERROR, mips64n32 has additional syscalls\n", mips64n32_syscall_iterate_name(i_mips64n32)); return 1; } if (i_parisc >= 0) { printf("%s: ERROR, parisc has additional syscalls\n", parisc_syscall_iterate_name(i_parisc)); } if (i_ppc >= 0) { printf("%s: ERROR, ppc has additional syscalls\n", ppc_syscall_iterate_name(i_ppc)); } if (i_ppc64 >= 0) { printf("%s: ERROR, ppc64 has additional syscalls\n", ppc64_syscall_iterate_name(i_ppc64)); return 1; } if (i_s390 >= 0) { printf("%s: ERROR, s390 has additional syscalls\n", s390_syscall_iterate_name(i_s390)); return 1; } if (i_s390x >= 0) { printf("%s: ERROR, s390x has additional syscalls\n", s390x_syscall_iterate_name(i_s390x)); return 1; } /* if we made it here, all is good */ return 0; }
static void load_chunk_regs(struct user *user, struct cp_sparc_window_regs *or, int stopped) { long *p = (long*)TRAMPOLINE_ADDR; char *code = (char*)TRAMPOLINE_ADDR; struct regs *r = (struct regs*)&user->regs; /* Create region for mini-resumer process. */ syscall_check( (long)mmap((void*)TRAMPOLINE_ADDR, PAGE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0), 0, "mmap"); /* munmap our custom malloc space */ *p++=0x82102000 | __NR_munmap; /* mov foo, %g1 */ *p++=0x11000000 | HIB(MALLOC_START); /* sethi foo, %o0 */ *p++=0x90122000 | LOB(MALLOC_START); /* or %o0, foo, %o0 */ *p++=0x13000000 | HIB(MALLOC_END-MALLOC_START); /* sethi foo, %o1 */ *p++=0x92126000 | LOB(MALLOC_END-MALLOC_START); /* or %o1, foo, %o1 */ *p++=0x91d02010; /* t 0x10 */ /* munmap resumer code except for us */ *p++=0x82102000 | __NR_munmap; /* mov foo, %g1 */ *p++=0x11000000 | HIB(RESUMER_START); /* sethi foo, %o0 */ *p++=0x90122000 | LOB(RESUMER_START); /* or %o0, foo, %o0 */ *p++=0x13000000 | HIB(RESUMER_END-RESUMER_START); /* sethi foo, %o1 */ *p++=0x92126000 | LOB(RESUMER_END-RESUMER_START); /* or %o1, foo, %o1 */ *p++=0x91d02010; /* t 0x10 */ /* raise a SIGSTOP if we were stopped */ if (0 && stopped) { *p++=0x82102000 | __NR_kill; /* mov foo, %g1 */ *p++=0x11000000 | HIB(0); /* sethi foo, %o0 */ *p++=0x90122000 | LOB(0); /* or %o0, foo, %o0 */ *p++=0x13000000 | HIB(SIGSTOP); /* sethi foo, %o1 */ *p++=0x92126000 | LOB(SIGSTOP); /* or %o1, foo, %o1 */ *p++=0x91d02010; /* t 0x10 */ } /* restore registers */ *p++=0x03000000 | HIB(r->r_g1); *p++=0x82106000 | LOB(r->r_g1); *p++=0x05000000 | HIB(r->r_g2); *p++=0x8410a000 | LOB(r->r_g2); *p++=0x07000000 | HIB(r->r_g3); *p++=0x8610e000 | LOB(r->r_g3); *p++=0x09000000 | HIB(r->r_g4); *p++=0x88112000 | LOB(r->r_g4); *p++=0x0b000000 | HIB(r->r_g5); *p++=0x8a116000 | LOB(r->r_g5); *p++=0x0d000000 | HIB(r->r_g6); *p++=0x8c11a000 | LOB(r->r_g6); *p++=0x0f000000 | HIB(r->r_g7); *p++=0x8e11e000 | LOB(r->r_g7); *p++=0x11000000 | HIB(r->r_o0); *p++=0x90122000 | LOB(r->r_o0); *p++=0x13000000 | HIB(r->r_o1); *p++=0x92126000 | LOB(r->r_o1); *p++=0x15000000 | HIB(r->r_o2); *p++=0x9412a000 | LOB(r->r_o2); *p++=0x17000000 | HIB(r->r_o3); *p++=0x9612e000 | LOB(r->r_o3); *p++=0x19000000 | HIB(r->r_o4); *p++=0x98132000 | LOB(r->r_o4); *p++=0x1b000000 | HIB(r->r_o5); *p++=0x9a136000 | LOB(r->r_o5); *p++=0x1d000000 | HIB(r->r_o6); *p++=0x9c13a000 | LOB(r->r_o6); *(long*)(code+0xffc) = r->r_o7; *p++=0x1f000000 | HIB(r->r_npc); *p++=0x9e13e000 | LOB(r->r_npc); *p++=0x21000000 | HIB(or->r_l0); *p++=0xb0142000 | LOB(or->r_l0); *p++=0x23000000 | HIB(or->r_l1); *p++=0xb2146000 | LOB(or->r_l1); *p++=0x25000000 | HIB(or->r_l2); *p++=0xb414a000 | LOB(or->r_l2); *p++=0x27000000 | HIB(or->r_l3); *p++=0xb614e000 | LOB(or->r_l3); *p++=0x29000000 | HIB(or->r_l4); *p++=0xb8152000 | LOB(or->r_l4); *p++=0x2b000000 | HIB(or->r_l5); *p++=0xba156000 | LOB(or->r_l5); *p++=0x2d000000 | HIB(or->r_l6); *p++=0xbc15a000 | LOB(or->r_l6); *p++=0x2f000000 | HIB(or->r_l7); *p++=0xbe15e000 | LOB(or->r_l7); *p++=0x31000000 | HIB(or->r_i0); *p++=0xb0162000 | LOB(or->r_i0); *p++=0x33000000 | HIB(or->r_i1); *p++=0xb2166000 | LOB(or->r_i1); *p++=0x35000000 | HIB(or->r_i2); *p++=0xb416a000 | LOB(or->r_i2); *p++=0x37000000 | HIB(or->r_i3); *p++=0xb616e000 | LOB(or->r_i3); *p++=0x39000000 | HIB(or->r_i4); *p++=0xb8172000 | LOB(or->r_i4); *p++=0x3b000000 | HIB(or->r_i5); *p++=0xba176000 | LOB(or->r_i5); *p++=0x3d000000 | HIB(or->r_i6); *p++=0xbc17a000 | LOB(or->r_i6); *p++=0x3f000000 | HIB(or->r_i7); *p++=0xbe17e000 | LOB(or->r_i7); /* jump back to where we were. */ *p++=0x81c3c000; /* jmp %o7, %g0 */ *p++=0xde002ffc; /* ld [ 0xfff ], %o7 */ }