// get current process before each bb executes // which will probably help us actually know the current process int osi_foo(CPUState *cpu, TranslationBlock *tb) { if (panda_in_kernel(cpu)) { OsiProc *p = get_current_process(cpu); //some sanity checks on what we think the current process is // this means we didnt find current task if (p->offset == 0) return 0; // or the name if (p->name == 0) return 0; // weird -- this is just not ok if (((int) p->pid) == -1) return 0; uint32_t n = strnlen(p->name, 32); // yuck -- name is one char if (n<2) return 0; uint32_t np = 0; for (uint32_t i=0; i<n; i++) { np += (isprint(p->name[i]) != 0); } // yuck -- name doesnt consist of solely printable characters if (np != n) return 0; target_ulong asid = panda_current_asid(cpu); if (running_procs.count(asid) == 0) { if (debug) printf ("adding asid=0x%x to running procs. cmd=[%s] task=0x%x\n", (unsigned int) asid, p->name, (unsigned int) p->offset); } if (running_procs.count(asid) != 0) { /* OsiProc *p2 = running_procs[asid]; // something there already if (p2) free_osiproc(p2); */ } running_procs[asid] = *p; } return 0; }
SYSCALL_HANDLER3(sys_select, uint32_t *fds, size_t n, int *ret) { process_t * process = get_current_process(); int val = 0; uint8_t sem = ksemget(SEM_NEW, SEM_CREATE); ksemctl(sem, SEM_SET, &val); size_t i, j; open_file_descriptor *ofd; for (i = 0; i < n; i++) { ofd = process->fd[fds[i]]; ofd->select_sem = sem; if (ofd->current_octet < ofd->inode->i_size) { // Found, exit ksemctl(sem, SEM_DEL, NULL); for (j = 0; j <= i; j++) { ofd->select_sem = 0; } *ret = fds[i]; return; } } ksemP(sem); for (i = 0; i < n; i++) { ofd = process->fd[fds[i]]; ofd->select_sem = 0; if (ofd->current_octet < ofd->inode->i_size) { *ret = fds[i]; } } ksemctl(sem, SEM_DEL, NULL); }
// get current process before each bb execs // which will probably help us actually know the current process int osi_foo(CPUState *env, TranslationBlock *tb) { if (panda_in_kernel(env)) { OsiProc *p = get_current_process(env); //some sanity checks on what we think the current process is // this means we didnt find current task if (p->offset == 0) return 0; // or the name if (p->name == 0) return 0; // this is just not ok if (((int) p->pid) == -1) return 0; uint32_t n = strnlen(p->name, 32); // name is one char? if (n<2) return 0; uint32_t np = 0; for (uint32_t i=0; i<n; i++) { np += (isprint(p->name[i]) != 0); } // name doesnt consist of solely printable characters // printf ("np=%d n=%d\n", np, n); if (np != n) return 0; target_ulong asid = panda_current_asid(env); if (running_procs.count(asid) == 0) { printf ("adding asid=0x%x to running procs. cmd=[%s] task=0x%x\n", (unsigned int) asid, p->name, (unsigned int) p->offset); } running_procs[asid] = *p; } return 0; }
SYSCALL_HANDLER3(sys_read, uint32_t fd, const void *buf, size_t *c) { ssize_t *t = (ssize_t*)c; if (buf == NULL) { kerr("buffer null !"); *t = -1; return; } process_t * process = get_current_process(); open_file_descriptor *ofd; if (process->fd[fd]) { ofd = process->fd[fd]; if(ofd->f_ops->read == NULL) { kerr("No \"read\" method for this device."); *t = -1; } else { *t = ofd->f_ops->read(ofd, (void*) buf, *c); } } else { *t = -1; } }
SYSCALL_HANDLER3(sys_sigprocmask, uint32_t how, sigset_t* set, sigset_t* oldset) { process_t* current = get_current_process(); /* On récupère l'ancien set */ if (oldset != NULL) *oldset = current->signal_data.mask; /* Si set est null, alors on fait rien. */ if (set == NULL) return; /* Et on met à jour le nouveau */ switch(how) { case SIG_SETMASK: current->signal_data.mask = *set; break; case SIG_UNBLOCK: current->signal_data.mask &= ~(*set); break; case SIG_BLOCK: current->signal_data.mask |= (*set); break; default: kerr("Invalid sigprocmask command (0x%x).", how); } }
int sys_psp_read_umd(int unk, void *buf, uint64_t sector, uint64_t ofs, uint64_t size) { uint64_t offset, dummy; int ret; #ifdef DEBUG DPRINTF("umd read %lx %lx %lx\n", sector, ofs, size); #endif if (!mutex) { object_handle_t obj_handle; void *object_table = get_current_process()->object_table; int ret = open_kernel_object(object_table, *(uint32_t *)(emulator_api_base+umd_mutex_offset), (void **)&mutex, &obj_handle, SYS_MUTEX_OBJECT); if (ret != 0) { #ifdef DEBUG DPRINTF("Cannot open user mutex, using an own one\n"); #endif mutex_create(&mutex, SYNC_PRIORITY, SYNC_NOT_RECURSIVE); user_mutex = 0; } else { #ifdef DEBUG DPRINTF("user mutex opened succesfully\n"); #endif user_mutex = 1; close_kernel_object_handle(object_table, obj_handle); } } mutex_lock(mutex, 0); offset = sector*0x800; if (ofs != 0) { offset = offset+0x800-ofs; } ret = cellFsLseek(umd_fd, offset, SEEK_SET, &dummy); if (ret != 0) { mutex_unlock(mutex); return ret; } ret = cellFsRead(umd_fd, get_secure_user_ptr(buf), size, &dummy); mutex_unlock(mutex); if (ret == 0) ret = (int)size; return ret; }
int mutex_release(struct mutex_s * mutex) { /* Vérification des paramètres */ if (mutex == NULL || mutex->owner != get_current_process()) { return -1; } mutex->owner = NULL; sem_up(&mutex->sem); return 0; }
SYSCALL_HANDLER3(sys_signal, uint32_t signum, sighandler_t handler, sighandler_t* ret) { process_t* current = get_current_process(); if (signum <= NSIG) { *ret = current->signal_data.handlers[signum]; current->signal_data.handlers[signum] = handler; } else { *ret = 0; } }
SYSCALL_HANDLER2(sys_dup, int oldfd, int *ret) { int i = 0; process_t* process = get_current_process(); // recherche d'une place dans la file descriptor table du process : while(process->fd[i]) { i++; } process->fd[i] = process->fd[oldfd]; *ret = i; }
void mutex_lock(mutex_t *mutex) { /* Mutexes only make sense in a preemptable environment */ if(!is_kernel_preempt()) return; /* Return of we already own the lock */ if(mutex->owner==get_current_process() && mutex->state==MUTEX_LOCKED) return; /* Disable kernel preemption */ disable_kernel_preempt(); /* Spin while Mutex is locked */ while(mutex->state==MUTEX_LOCKED){ mutex_wait(); } /* Finally lock the Mutex */ mutex->state=MUTEX_LOCKED; mutex->owner=get_current_process(); /* Now we can safely re-enable preemption */ enable_kernel_preempt(); }
//pszFilename must have room for at least MaxPath+1 characters static inline bool get_file_name_from_handle_function (void * hFile, wchar_t *pszFilename, std::size_t length, std::size_t &out_length) { if(length <= MaxPath) { return false; } void *hiPSAPI = load_library("PSAPI.DLL"); if (0 == hiPSAPI) return 0; class library_unloader { void *lib_; public: library_unloader(void *module) : lib_(module) {} ~library_unloader() { free_library(lib_); } } unloader(hiPSAPI); // Pointer to function getMappedFileName() in PSAPI.DLL GetMappedFileName_t pfGMFN = (GetMappedFileName_t)get_proc_address(hiPSAPI, "GetMappedFileNameW"); if (! pfGMFN) { return 0; // Failed: unexpected error } bool bSuccess = false; // Create a file mapping object. void * hFileMap = create_file_mapping(hFile, page_readonly, 0, 1, 0); if(hFileMap) { // Create a file mapping to get the file name. void* pMem = map_view_of_file_ex(hFileMap, file_map_read, 0, 0, 1, 0); if (pMem) { out_length = pfGMFN(get_current_process(), pMem, pszFilename, MaxPath); if(out_length) { bSuccess = true; } unmap_view_of_file(pMem); } close_handle(hFileMap); } return(bSuccess); }
int before_block_exec(CPUState *env, TranslationBlock *tb) { int i; OsiProc *current = get_current_process(env); printf("Current process: %s PID:" TARGET_FMT_ld " PPID:" TARGET_FMT_ld "\n", current->name, current->pid, current->ppid); OsiModules *ms = get_libraries(env, current); if (ms == NULL) { printf("No mapped dynamic libraries.\n"); } else { printf("Dynamic libraries list (%d libs):\n", ms->num); for (i = 0; i < ms->num; i++) printf("\t0x" TARGET_FMT_lx "\t" TARGET_FMT_ld "\t%-24s %s\n", ms->module[i].base, ms->module[i].size, ms->module[i].name, ms->module[i].file); } printf("\n"); OsiProcs *ps = get_processes(env); if (ps == NULL) { printf("Process list not available.\n"); } else { printf("Process list (%d procs):\n", ps->num); for (i = 0; i < ps->num; i++) printf(" %-16s\t" TARGET_FMT_ld "\t" TARGET_FMT_ld "\n", ps->proc[i].name, ps->proc[i].pid, ps->proc[i].ppid); } printf("\n"); OsiModules *kms = get_modules(env); if (kms == NULL) { printf("No mapped kernel modules.\n"); } else { printf("Kernel module list (%d modules):\n", kms->num); for (i = 0; i < kms->num; i++) printf("\t0x" TARGET_FMT_lx "\t" TARGET_FMT_ld "\t%-24s %s\n", kms->module[i].base, kms->module[i].size, kms->module[i].name, kms->module[i].file); } printf("\n-------------------------------------------------\n\n"); // Cleanup free_osiproc(current); free_osiprocs(ps); free_osimodules(ms); return 0; }
int mutex_acquire(struct mutex_s * mutex) { /* Vérification des paramètres */ if (mutex == NULL) { return -1; } /* Processus : * - sem_down bloque le process courant si le mutex est déjà bloqué * - immédiatement après, on est sûr que le processus courant a * vérouillé le mutex */ /* FIXME fait planter le kernel */ sem_down(&mutex->sem); mutex->owner = get_current_process(); return 0; }
SYSCALL_HANDLER2(sys_dup2, int oldfd, int *newfd) { process_t* process = get_current_process(); if (process->fd[oldfd]) { if (process->fd[*newfd]) { if (process->fd[*newfd]->f_ops->close != NULL) { process->fd[*newfd]->f_ops->close(process->fd[*newfd]); } } process->fd[*newfd] = process->fd[oldfd]; } else { *newfd = -1; } }
SYSCALL_HANDLER3(sys_ioctl, uint32_t *fd, unsigned int request, void *data) { process_t * process = get_current_process(); open_file_descriptor *ofd; if (process->fd[*fd]) { ofd = process->fd[*fd]; if (ofd->f_ops->ioctl == NULL) { kerr("No \"ioctl\" method for this device."); *fd = -1; } else { *fd = ofd->f_ops->ioctl(ofd, request, data); } } }
SYSCALL_HANDLER3(sys_seek, uint32_t fd, long *offset, int whence) { process_t * process = get_current_process(); open_file_descriptor *ofd; if (process->fd[fd]) { ofd = process->fd[fd]; if(ofd->f_ops->seek == NULL) { kerr("No \"seek\" method for this device."); *offset = -1; } else { ofd->f_ops->seek(ofd, *offset, whence); *offset = ofd->current_octet; } } }
SYSCALL_HANDLER3(sys_write, uint32_t fd, const void *buf, size_t *c) { process_t * process = get_current_process(); ssize_t *t = (ssize_t*)c; open_file_descriptor *ofd; if (process->fd[fd]) { ofd = process->fd[fd]; if(ofd->f_ops->write == NULL) { kerr("No \"write\" method for this device."); *t = -1; } else { *t = ofd->f_ops->write(ofd, buf, *c); } } else { *t = -1; } }
/* TODO: d'après POSIX, kill(-1, sig) doit envoyer le signal à tous les processus possibles... */ SYSCALL_HANDLER3(sys_kill, int pid, int signum, int* ret) { process_t* process = find_process(pid); int retour = -1; if(process != NULL) { retour = sigaddset( &(process->signal_data.pending_set), signum ); klog("%d sending signal %s(%d) to pid %d.", get_current_process()->pid, signal_names[signum], signum, pid); } else { kerr("Process not found (%d).", pid); } if(ret!=NULL) *ret = retour; }
int ksemP(uint8_t key) { int ret = -1; sem_t* sem = &semaphores[key]; if (sem->allocated) { /* Si le sémaphore est libre, on le prend, sinon, on attend */ if(sem->value >= 1) { sem->value--; } else { process_t* proc = get_current_process(); /* Si on attend, on met le pid dans la file d'attente pour pouvoir traiter le processus quand le semaphore sera libre */ sem_fifo_put(&(sem->fifo), proc->pid); set_state_waiting(); } ret = 0; } return ret; }
uintptr_t map_virtual_virtual(uintptr_t* _vastart, uintptr_t vaend, bool readonly) { uintptr_t vastart = *_vastart; uintptr_t vaoffset = vastart % 0x1000; vastart = ALIGN_DOWN(vastart, 0x1000); vaend = ALIGN_UP(vaend, 0x1000); proc_t* proc = get_current_process(); mmap_area_t** _hole = find_va_hole(proc, vaend-vastart, 0x1000); mmap_area_t* hole = *_hole; if (hole == NULL) { return 0; } hole->mtype = kernel_allocated_heap_data; uintptr_t temporary = hole->vastart; if (!map_range(_vastart, vaend, &temporary, hole->vaend, true, readonly, false, proc->pml4)) { free_mmap_area(hole, _hole, proc); return 0; } return hole->vastart+vaoffset; }
int coverage_before_block_exec(CPUState *env, TranslationBlock *tb) { #ifdef CONFIG_SOFTMMU OsiProc *p = get_current_process(env); uint64_t asid = panda_current_asid(env); if (process_asid == 0) { // look for process matching the one we want if (p && p->name) { if (strcmp(process_name, p->name) == 0) { process_asid = asid; printf ("coverage plugin: saw cr3=0x%" PRIx64 " for process=[%s]\n", asid, process_name); } } } if (process_asid !=0 && process_asid == asid) { // collect bb for this asid process_bb.insert(tb->pc); // and count number of bb executed (regardless of repetetion) process_total_bb ++; } free_osiproc(p); #endif return 0; }
void *virtual_alloc(void *addr, uintptr_t size, uint32_t allocation_type, uint32_t protection) { return virtual_alloc_ex(get_current_process(), addr, size, allocation_type, protection); }
int virtual_free(const void *addr, uintptr_t size, uint32_t free_type) { return virtual_free_ex(get_current_process(), addr, size, free_type); }
/* Checks if given address range in the context of the current process is under * surveillance. * Param: * addr - Starting address of a range. * size - Range size. * Return: * boolean: 1 if address range contains memory that require access violation * detection, or 0 if given address range is in no interest to the memchecker. */ int memcheck_is_checked(target_ulong addr, uint32_t size) { return procdesc_contains_allocs(get_current_process(), addr, size) ? 1 : 0; }
NTSTATUS virtual_protect(const void *addr, uintptr_t size, uint32_t protection) { return virtual_protect_ex(get_current_process(), addr, size, protection); }
/* Validates access to a guest address. * Param: * addr - Virtual address in the guest space where memory is accessed. * data_size - Size of the accessed data. * proc_ptr - Upon exit from this routine contains pointer to the process * descriptor for the current process, or NULL, if no such descriptor has * been found. * desc_ptr - Upon exit from this routine contains pointer to the allocation * descriptor matching given address range, or NULL, if allocation * descriptor for the validated memory range has not been found. * Return: * 0 if access to the given guest address range doesn't violate anything, or * 1 if given guest address range doesn't match any entry in the current * process allocation descriptors map, or * -1 if a violation has been detected. */ static int memcheck_common_access_validation(target_ulong addr, uint32_t data_size, ProcDesc** proc_ptr, MallocDescEx** desc_ptr) { MallocDescEx* desc; target_ulong validating_range_end; target_ulong user_range_end; ProcDesc* proc = get_current_process(); *proc_ptr = proc; if (proc == NULL) { *desc_ptr = NULL; return 1; } desc = procdesc_find_malloc_for_range(proc, addr, data_size); *desc_ptr = desc; if (desc == NULL) { return 1; } /* Verify that validating address range doesn't start before the address * available to the user. */ if (addr < mallocdesc_get_user_ptr(&desc->malloc_desc)) { // Stepped on the prefix guarding area. return -1; } validating_range_end = addr + data_size; user_range_end = mallocdesc_get_user_alloc_end(&desc->malloc_desc); /* Verify that validating address range ends inside the user block. * We may step on the suffix guarding area because of alignment issue. * For example, the application code reads last byte in the allocated block * with something like this: * * char last_byte_value = *(char*)last_byte_address; * * and this code got compiled into something like this: * * mov eax, [last_byte_address]; * mov [last_byte_value], al; * * In this case we will catch a read from the suffix area, even though * there were no errors in the code. So, in order to prevent such "false * negative" alarms, lets "forgive" this violation. * There is one bad thing about this "forgivness" though, as it may very * well be, that in real life some of these "out of bound" bytes will cross * page boundaries, marching into a page that has not been mapped to the * process. */ if (validating_range_end <= user_range_end) { // Validating address range is fully contained inside the user block. return 0; } /* Lets see if this AV is caused by an alignment issue.*/ if ((validating_range_end - user_range_end) < data_size) { /* Could be an alignment. */ return 0; } return -1; }
NTSTATUS virtual_read(void *addr, void *buffer, uintptr_t *size) { return virtual_read_ex(get_current_process(), addr, buffer, size); }
case BASIC_PLUGINS_HASH: return "basic_plugins.sprx"; break;*/ default: return "UNKNOWN"; break; } } #endif LV2_HOOKED_FUNCTION_PRECALL_2(int, post_lv1_call_99_wrapper, (uint64_t *spu_obj, uint64_t *spu_args)) { // This replaces an original patch of psjailbreak, since we need to do more things process_t process = get_current_process(); saved_buf = (void *)spu_args[0x20/8]; saved_sce_hdr = (void *)spu_args[8/8]; if (process) { caller_process = process->pid; #ifdef DEBUG //DPRINTF("caller_process = %08X\n", caller_process); #endif } return 0; }
/*pgtable sequential scan and count for __access_bits.*/ static int scan_pgtable(void) { pgd_t *pgd = NULL; pud_t *pud = NULL; pmd_t *pmd = NULL; pte_t *ptep, pte; spinlock_t *ptl; struct mm_struct *mm; struct vm_area_struct *vma; unsigned long start = 0; /*the start of address.*/ unsigned long end = 0; /*the end of address.*/ unsigned long address = 0; /* the address of vma.*/ int number_hotpages = 0; /* the number of hot pages */ int number_vpages = 0; int cycle_index = 0; /* the loop counter, which denotes ITERATIONS. */ /* the array that records the number of hot page in every cycle */ int hot_page[ITERATIONS]; int number_current_pg = 0; int pg_count = 0; int j = 0; int times = 0; /* records reuse time*/ /* some variables that describe page "heat" */ int hig = 0; int mid = 0; int low = 0; int llow = 0; int lllow = 0; int llllow = 0; int all_pages = 0;/* the total number of pages */ /*the average number of hot pages in each iteration.*/ long avg_hotpage=0; /*the total number of memory accesses across all pages*/ long num_access=0; /* avg utilization of each page */ int avg_page_utilization = 0; /*get the handle of current running benchmark.*/ struct task_struct *bench_process = get_current_process(); if(bench_process == NULL) { printk("sysmon: get no process handle in scan_pgtable function...exit&trying again...\n"); return 0; } else /* get the process*/ mm = bench_process->mm; if(mm == NULL) { printk("sysmon: error mm is NULL, return back & trying...\n"); return 0; } for(j = 0; j < PAGE_ALL; j++) page_heat[j] = -1; for(j = 0; j < ITERATIONS; j++) { hot_page[j] = 0; reuse_time[j] = 0; dirty_page[j] = 0; } /*yanghao*/ times = 0; for(cycle_index = 0; cycle_index < ITERATIONS; cycle_index++) { number_hotpages = 0; /*scan each vma*/ for(vma = mm->mmap; vma; vma = vma->vm_next) { start = vma->vm_start; end = vma->vm_end; mm = vma->vm_mm; /*in each vma, we check all pages*/ for(address = start; address < end; address += PAGE_SIZE) { /*scan page table for each page in this VMA*/ pgd = pgd_offset(mm, address); if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) continue; pud = pud_offset(pgd, address); if (pud_none(*pud) || unlikely(pud_bad(*pud))) continue; pmd = pmd_offset(pud, address); if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) continue; ptep = pte_offset_map_lock(mm, pmd, address, &ptl); pte = *ptep; if(pte_present(pte)) { if(pte_young(pte)) /*hot page*/ { /*re-set and clear _access_bits to 0*/ pte = pte_mkold(pte); set_pte_at(mm, address, ptep, pte); /*yanghao:re-set and clear _dirty_bits to 0*/ pte = pte_mkclean(pte); set_pte_at(mm, address, ptep, pte); } } else /*no page pte_none*/ { pte_unmap_unlock(ptep, ptl); continue; } pte_unmap_unlock(ptep, ptl); page_counts++; } } /*count the number of hot pages*/ if(bench_process == NULL) { printk("sysmon: get no process handle in scan_pgtable function...exit&trying again...\n"); return 0; } else /*get the process*/ mm = bench_process->mm; if(mm == NULL) { printk("sysmon: error mm is NULL, return back & trying...\n"); return 0; } number_vpages = 0; sampling_interval = page_counts / 250; /*yanghao:*/ page_counts = 0; for(vma = mm->mmap; vma; vma = vma->vm_next) { start = vma->vm_start; end = vma->vm_end; /*scan each page in this VMA*/ mm = vma->vm_mm; pg_count = 0; for(address = start; address < end; address += PAGE_SIZE) { /*scan page table for each page in this VMA*/ pgd = pgd_offset(mm, address); if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) continue; pud = pud_offset(pgd, address); if (pud_none(*pud) || unlikely(pud_bad(*pud))) continue; pmd = pmd_offset(pud, address); if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) continue; ptep = pte_offset_map_lock(mm, pmd, address, &ptl); pte = *ptep; if(pte_present(pte)) { if(pte_young(pte)) /* hot pages*/ { number_current_pg = pg_count + number_vpages; page_heat[number_current_pg]++; hot_page[cycle_index]++; /*yanghao:*/ if (page_counts == random_page) { times++; if (pte_dirty(pte)) dirty_page[cycle_index] = 1; } } else { if (page_counts == random_page) reuse_time[times]++; } } pg_count++; pte_unmap_unlock(ptep, ptl); page_counts++; } number_vpages += (int)(end - start)/PAGE_SIZE; } } /*yanghao:cal. the No. of random_page*/ random_page += sampling_interval; if(random_page >= page_counts) random_page=page_counts / 300; /*****************************OUTPUT************************************/ for(j = 0; j < PAGE_ALL; j++) { if(page_heat[j] < VH && page_heat[j] > H) hig++; if(page_heat[j] > M && page_heat[j] <= H) mid++; if(page_heat[j] <= M && page_heat[j] > L) low++; if(page_heat[j] > VL_MAX && page_heat[j] <= L) llow++; if(page_heat[j] > VL_MIN && page_heat[j] <= VL_MAX) lllow++; if(page_heat[j] >= 0 && page_heat[j] <= VL_MIN) llllow++; if(page_heat[j] > -1) all_pages++; } /*the values reflect the accessing frequency of each physical page.*/ printk("[LOG: after sampling (%d loops) ...] ",ITERATIONS); printk("the values denote the physical page accessing frequence.\n"); printk("-->hig (150,200) is %d. Indicating the number of re-used pages is high.\n",hig); printk("-->mid (100,150] is %d.\n",mid); printk("-->low (64,100] is %d.\n",low); printk("-->llow (10,64] is %d. In locality,no too many re-used pages.\n",llow); printk("-->lllow (5,10] is %d.\n",lllow); printk("-->llllow [1,5] is %d.\n",llllow); for(j = 0;j < ITERATIONS; j++) avg_hotpage += hot_page[j]; avg_hotpage /= (j+1); /* * new step@20140704 * (1)the different phases of memory utilization * (2)the avg. page accessing utilization * (3)memory pages layout and spectrum */ for(j = 0; j < PAGE_ALL; j++) if(page_heat[j] > -1) /*the page that is accessed at least once.*/ num_access += (page_heat[j] + 1); printk("the total number of memory accesses is %ld, the average is %ld\n", num_access, num_access / ITERATIONS); avg_page_utilization = num_access / all_pages; printk("Avg hot pages num is %ld, all used pages num is %d, avg utilization of each page is %d\n", avg_hotpage, all_pages, avg_page_utilization); /*yanghao:print the information about reuse-distance*/ if ((times == 0) && (reuse_time[0] ==0)) printk("the page No.%d is not available.",random_page); else { if ((times == 0) && (reuse_time[0] == 0)) printk("the page No.%d was not used in this 200 loops.",random_page); else { if (times < ITERATIONS) times++; printk("the reusetime of page No.%d is:",random_page); for (j = 0; j < times; j++) printk("%d ",reuse_time[j]); printk("\n"); printk("the total number of the digit above denotes the sum that page NO.%d be accessd in %d loops.\n", random_page,ITERATIONS); printk("each digit means the sum loops that between current loop and the last loop.\n"); } } printk("\n\n"); return 1; }
int sys_psp_read_header(int fd, char *buf, uint64_t nbytes, uint64_t *nread) { int ret; uint32_t n, unk2; uint64_t umd_size; sys_prx_id_t *list; uint32_t *unk; process_t process; #ifdef DEBUG DPRINTF("umd read header: %p %lx\n", buf, nbytes); #endif buf = get_secure_user_ptr(buf); nread = get_secure_user_ptr(nread); if (!umd_file || nbytes != 0x100) return EABORT; pemucorelib_base = 0; emulator_api_base = 0; list = alloc(SPRX_NUM*sizeof(sys_prx_module_info_t), 0x35); unk = alloc(SPRX_NUM*sizeof(uint32_t), 0x35); process = get_current_process(); ret = prx_get_module_list(process, list, unk, SPRX_NUM, &n, &unk2); if (ret == 0) { char *filename = alloc(256, 0x35); sys_prx_segment_info_t *segments = alloc(sizeof(sys_prx_segment_info_t), 0x35); for (int i = 0; i < SPRX_NUM; i++) { sys_prx_module_info_t modinfo; memset(&modinfo, 0, sizeof(sys_prx_module_info_t)); modinfo.filename_size = 256; modinfo.segments_num = 1; if (prx_get_module_info(process, list[i], &modinfo, filename, segments) == 0) { if (strstr(filename, "/emulator_api.sprx")) { emulator_api_base = segments[0].base; #ifdef DEBUG DPRINTF("emulator_api base = %08lx\n", emulator_api_base); #endif } else if (strstr(filename, "/PEmuCoreLib.sprx")) { pemucorelib_base = segments[0].base; #ifdef DEBUG DPRINTF("PEmuCoreLib base = %08lx\n", pemucorelib_base); #endif } } } if (pemucorelib_base == 0 || emulator_api_base == 0) ret = EABORT; dealloc(filename, 0x35); dealloc(segments, 0x35); } dealloc(list, 0x35); dealloc(unk, 0x35); if (ret != 0) return ret; ret = cellFsOpen(umd_file, CELL_FS_O_RDONLY, &umd_fd, 0, NULL, 0); if (ret != 0) return ret; cellFsLseek(umd_fd, 0, SEEK_END, &umd_size); // Fake header. We will write only values actually used memset(buf, 0, 0x100); *(uint32_t *)(buf+0x0c) = 0x10; *(uint32_t *)(buf+0x64) = (umd_size/0x800)-1; // Last sector of umd strncpy(buf+0x70, psp_id, 10); #ifdef DEBUG DPRINTF("ID: %s\n", psp_id); #endif if (mutex && user_mutex) { mutex = NULL; user_mutex = 0; } *nread = 0x100; return 0; }