static void command_get_children_cache_client(void * x) { GetChildrenArgs * args = (GetChildrenArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; StackFrame * frame_info = NULL; RegisterDefinition * defs = NULL; RegisterDefinition * parent = NULL; Trap trap; if (set_trap(&trap)) { if (id2register(args->id, &ctx, &frame, &parent) == 0) { if (frame != STACK_TOP_FRAME && get_frame_info(ctx, frame, &frame_info) < 0) exception(errno); } else if (id2frame(args->id, &ctx, &frame) == 0) { if (get_frame_info(ctx, frame, &frame_info) < 0) exception(errno); } else { ctx = id2ctx(args->id); frame = STACK_TOP_FRAME; } if (ctx != NULL) defs = get_reg_definitions(ctx); clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); write_stream(&c->out, '['); if (defs != NULL) { int cnt = 0; RegisterDefinition * reg_def; for (reg_def = defs; reg_def->name != NULL; reg_def++) { if (reg_def->parent != parent) continue; if (frame < 0 || frame_info->is_top_frame || reg_def->size == 0 || read_reg_value(frame_info, reg_def, NULL) == 0) { if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out, register2id(ctx, frame, reg_def)); cnt++; } } } write_stream(&c->out, ']'); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); }
int get_symbol_address(const Symbol * sym, ContextAddress * addr) { SYMBOL_INFO * info = NULL; assert(sym->magic == SYMBOL_MAGIC); if (sym->address != 0) { *addr = sym->address; return 0; } if (sym->base || sym->info) { errno = ERR_INV_CONTEXT; return -1; } if (get_sym_info(sym, sym->index, &info) < 0) return -1; if (is_register(info)) { set_errno(ERR_INV_CONTEXT, "Register variable"); return -1; } *addr = (ContextAddress)info->Address; if (is_frame_relative(info)) { StackFrame * frame_info; int frame = sym->frame + STACK_NO_FRAME; if (get_frame_info(sym->ctx, frame, &frame_info) < 0) return -1; *addr += frame_info->fp - sizeof(ContextAddress) * 2; } return 0; }
static int __init frame_info_init(void) { int i; #ifdef CONFIG_KALLSYMS char *modname; char namebuf[KSYM_NAME_LEN + 1]; unsigned long start, size, ofs; extern char __sched_text_start[], __sched_text_end[]; extern char __lock_text_start[], __lock_text_end[]; start = (unsigned long)__sched_text_start; for (i = 0; i < ARRAY_SIZE(mfinfo); i++) { if (start == (unsigned long)schedule) schedule_frame = &mfinfo[i]; if (!kallsyms_lookup(start, &size, &ofs, &modname, namebuf)) break; mfinfo[i].func = (void *)(start + ofs); mfinfo[i].func_size = size; start += size - ofs; if (start >= (unsigned long)__lock_text_end) break; if (start == (unsigned long)__sched_text_end) start = (unsigned long)__lock_text_start; } #else mfinfo[0].func = schedule; schedule_frame = &mfinfo[0]; #endif for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++) get_frame_info(&mfinfo[i]); mfinfo_num = i; return 0; }
static int encode(ID3ASFilterContext *context, AVFrame *frame, AVPacket *pkt) { int got_packet_ptr = 0; int ret = 0; codec_t *this = context->priv_data; this->have_encoded_frames = 1; ret = avcodec_encode_video2(this->context, pkt, frame, &got_packet_ptr); if (ret != 0) { ERRORFMT("avcodec_encode_video2 failed with %d", ret); } if (got_packet_ptr) { frame_info *frame_info = get_frame_info(this->frame_info_queue, pkt->pts, 0); // And rescale back to "erlang time" pkt->pts = av_rescale_q(pkt->pts, this->context->time_base, NINETY_KHZ); pkt->dts = av_rescale_q(pkt->dts, this->context->time_base, NINETY_KHZ); pkt->duration = av_rescale_q(pkt->duration, this->context->time_base, NINETY_KHZ); write_output_from_packet(this->pin_name, this->stream_id, this->context, pkt, frame_info); free(frame_info); } return got_packet_ptr; }
static LocationExpressionState * evaluate_location(Context * ctx, int frame, LocationInfo * loc_info) { Trap trap; StackFrame * frame_info = NULL; LocationExpressionState * state = NULL; static uint64_t args[] = { 0, 0 }; if (frame != STACK_NO_FRAME && get_frame_info(ctx, frame, &frame_info) < 0) return NULL; if (!set_trap(&trap)) return NULL; state = evaluate_location_expression(ctx, frame_info, loc_info->value_cmds.cmds, loc_info->value_cmds.cnt, args, loc_info->args_cnt); clear_trap(&trap); return state; }
static int get_stack_frame(Context * ctx, int frame, ContextAddress ip, IMAGEHLP_STACK_FRAME * stack_frame) { memset(stack_frame, 0, sizeof(IMAGEHLP_STACK_FRAME)); if (frame == STACK_NO_FRAME) { stack_frame->InstructionOffset = ip; } else if (ctx->parent != NULL) { uint64_t v = 0; StackFrame * frame_info; if (get_frame_info(ctx, frame, &frame_info) < 0) return -1; if (read_reg_value(frame_info, get_PC_definition(ctx), &v) < 0) return -1; stack_frame->InstructionOffset = v; } return 0; }
static void command_get_cache_client(void * x) { GetArgs * args = (GetArgs *)x; Channel * c = cache_channel(); Trap trap; bbf_pos = 0; if (set_trap(&trap)) { int frame = 0; Context * ctx = NULL; RegisterDefinition * reg_def = NULL; if (id2register(args->id, &ctx, &frame, ®_def) < 0) exception(errno); if (ctx->exited) exception(ERR_ALREADY_EXITED); if ((ctx->reg_access & REG_ACCESS_RD_STOP) != 0) { check_all_stopped(ctx); } if ((ctx->reg_access & REG_ACCESS_RD_RUNNING) == 0) { if (!ctx->stopped && context_has_state(ctx)) str_exception(ERR_IS_RUNNING, "Cannot read register if not stopped"); } if (reg_def->size > bbf_len) { bbf_len += 0x100 + reg_def->size; bbf = (uint8_t *)loc_realloc(bbf, bbf_len); } bbf_pos = reg_def->size; memset(bbf, 0, reg_def->size); if (frame < 0 || is_top_frame(ctx, frame)) { if (context_read_reg(ctx, reg_def, 0, reg_def->size, bbf) < 0) exception(errno); } else { StackFrame * info = NULL; if (get_frame_info(ctx, frame, &info) < 0) exception(errno); if (read_reg_bytes(info, reg_def, 0, reg_def->size, bbf) < 0) exception(errno); } clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); json_write_binary(&c->out, bbf, bbf_pos); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); }
unsigned int kheap_physical_address(unsigned int virtual_address) { //TODO: [PROJECT 2016 - Kernel Dynamic Allocation/Deallocation] kheap_physical_address() // Write your code here, remove the panic and write your code //panic("kheap_physical_address() is not implemented yet...!!"); //return the physical address corresponding to given virtual_address //refer to the project documentation for the detailed steps uint32* pageTable = NULL; struct Frame_Info* frameInfo = NULL; frameInfo = get_frame_info(ptr_page_directory, (void*) virtual_address, &pageTable); if(frameInfo != NULL) return (uint32) to_physical_address(frameInfo); //change this "return" according to your answer return 0; }
/* used by show_backtrace() */ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, unsigned long pc, unsigned long ra) { unsigned long stack_page; struct mips_frame_info info; char *modname; char namebuf[KSYM_NAME_LEN + 1]; unsigned long size, ofs; int leaf; stack_page = (unsigned long)task_stack_page(task); if (!stack_page) return 0; if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf)) return 0; if (ofs == 0) return 0; info.func = (void *)(pc - ofs); info.func_size = ofs; /* analyze from start to ofs */ leaf = get_frame_info(&info); if (leaf < 0) return 0; if (*sp < stack_page || *sp + info.frame_size > stack_page + THREAD_SIZE - 32) return 0; if (leaf) /* * For some extreme cases, get_frame_info() can * consider wrongly a nested function as a leaf * one. In that cases avoid to return always the * same value. */ pc = pc != ra ? ra : 0; else pc = ((unsigned long *)(*sp))[info.pc_offset]; *sp += info.frame_size; return __kernel_text_address(pc) ? pc : 0; }
void kfree(void* virtual_address) { //TODO: [PROJECT 2016 - Kernel Dynamic Allocation/Deallocation] kfree() // Write your code here, remove the panic and write your code //panic("kfree() is not implemented yet...!!"); //get the size of the given allocation using its address //refer to the project documentation for the detailed steps //validate the virtual address if((uint32) virtual_address < KERNEL_HEAP_START || (uint32) virtual_address >= KERNEL_HEAP_MAX) return; //check the given virtual address uint32* pageTable = NULL; struct Frame_Info* frameInfo = NULL; frameInfo = get_frame_info(ptr_page_directory, virtual_address, &pageTable); if(frameInfo == NULL) return; //good!, then searching about the block int blockIndex = findBlock(virtual_address); if(blockIndex == -1) return; //now we can unmap this block, see it's easy uint32 va; for(va = (uint32) virtual_address; va < (uint32) virtual_address + keepBlocks[blockIndex].blockSize; va += PAGE_SIZE) //unmap block pages unmap_frame(ptr_page_directory, (void*) va); //delete the unmaped block from the keepBlock array int i; for(i = blockIndex; i < nextBlock - 1; i++) keepBlocks[i] = keepBlocks[i + 1]; nextBlock--; //TODO: [PROJECT 2016 - BONUS1] Implement a Kernel allocation strategy // Instead of the continuous allocation/deallocation, implement one of // the strategies NEXT FIT, BEST FIT, .. etc }
void m68k_pop_frame () { register FRAME frame = get_current_frame (); register CORE_ADDR fp; register int regnum; struct frame_saved_regs fsr; struct frame_info *fi; char raw_buffer[12]; fi = get_frame_info (frame); fp = fi -> frame; get_frame_saved_regs (fi, &fsr); #if defined (HAVE_68881) for (regnum = FP0_REGNUM + 7 ; regnum >= FP0_REGNUM ; regnum--) { if (fsr.regs[regnum]) { read_memory (fsr.regs[regnum], raw_buffer, 12); write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); } } #endif for (regnum = FP_REGNUM - 1 ; regnum >= 0 ; regnum--) { if (fsr.regs[regnum]) { write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); } } if (fsr.regs[PS_REGNUM]) { write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); } write_register (FP_REGNUM, read_memory_integer (fp, 4)); write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); write_register (SP_REGNUM, fp + 8); flush_cached_frames (); set_current_frame (create_new_frame (read_register (FP_REGNUM), read_pc ())); }
static int __init frame_info_init(void) { int i; #ifdef CONFIG_KALLSYMS char *modname; char namebuf[KSYM_NAME_LEN + 1]; unsigned long start, size, ofs; extern char __sched_text_start[], __sched_text_end[]; extern char __lock_text_start[], __lock_text_end[]; start = (unsigned long)__sched_text_start; for (i = 0; i < ARRAY_SIZE(mfinfo); i++) { if (start == (unsigned long)schedule) schedule_frame = &mfinfo[i]; if (!kallsyms_lookup(start, &size, &ofs, &modname, namebuf)) break; mfinfo[i].func = (void *)(start + ofs); mfinfo[i].func_size = size; start += size - ofs; if (start >= (unsigned long)__lock_text_end) break; if (start == (unsigned long)__sched_text_end) start = (unsigned long)__lock_text_start; } #else mfinfo[0].func = schedule; schedule_frame = &mfinfo[0]; #endif for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++) get_frame_info(mfinfo + i); /* * Without schedule() frame info, result given by * thread_saved_pc() and get_wchan() are not reliable. */ if (schedule_frame->pc_offset < 0) printk("Can't analyze schedule() prologue at %p\n", schedule); mfinfo_num = i; return 0; }
static void check_location_list(Location * locs, unsigned cnt, int setm) { unsigned pos; for (pos = 0; pos < cnt; pos++) { Location * loc = locs + pos; if (id2register(loc->id, &loc->ctx, &loc->frame, &loc->reg_def) < 0) exception(errno); if (loc->ctx->exited) exception(ERR_ALREADY_EXITED); if ((loc->ctx->reg_access & setm ? REG_ACCESS_WR_STOP : REG_ACCESS_RD_STOP) != 0) { check_all_stopped(loc->ctx); } if ((loc->ctx->reg_access & setm ? REG_ACCESS_WR_RUNNING : REG_ACCESS_RD_RUNNING) == 0) { if (!loc->ctx->stopped && context_has_state(loc->ctx)) str_fmt_exception(ERR_IS_RUNNING, "Cannot %s register if not stopped", setm ? "write" : "read"); } if (loc->offs + loc->size > loc->reg_def->size) exception(ERR_INV_DATA_SIZE); if (loc->frame < 0 || is_top_frame(loc->ctx, loc->frame)) continue; if (setm) exception(ERR_INV_CONTEXT); if (get_frame_info(loc->ctx, loc->frame, &loc->frame_info) < 0) exception(errno); } }
static int __init frame_info_init(void) { unsigned long size = 0; #ifdef CONFIG_KALLSYMS unsigned long ofs; kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs); #endif schedule_mfi.func = schedule; schedule_mfi.func_size = size; get_frame_info(&schedule_mfi); /* */ if (schedule_mfi.pc_offset < 0) printk("Can't analyze schedule() prologue at %p\n", schedule); return 0; }
static int __init frame_info_init(void) { unsigned long size = 0; #ifdef CONFIG_KALLSYMS unsigned long ofs; kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs); #endif schedule_mfi.func = schedule; schedule_mfi.func_size = size; get_frame_info(&schedule_mfi); /* * Without schedule() frame info, result given by * thread_saved_pc() and get_wchan() are not reliable. */ if (schedule_mfi.pc_offset < 0) printk("Can't analyze schedule() prologue at %p\n", schedule); return 0; }
static int __init frame_info_init(void) { int i, found; for (i = 0; i < ARRAY_SIZE(mfinfo); i++) if (get_frame_info(&mfinfo[i])) return -1; schedule_frame = mfinfo[0]; /* bubble sort */ do { struct mips_frame_info tmp; found = 0; for (i = 1; i < ARRAY_SIZE(mfinfo); i++) { if (mfinfo[i-1].func > mfinfo[i].func) { tmp = mfinfo[i]; mfinfo[i] = mfinfo[i-1]; mfinfo[i-1] = tmp; found = 1; } } } while (found); mips_frame_info_initialized = 1; return 0; }
/* generic stack unwinding function */ unsigned long notrace unwind_stack_by_address(unsigned long stack_page, unsigned long *sp, unsigned long pc, unsigned long *ra) { struct mips_frame_info info; unsigned long size, ofs; int leaf; extern void ret_from_irq(void); extern void ret_from_exception(void); if (!stack_page) return 0; /* * If we reached the bottom of interrupt context, * return saved pc in pt_regs. */ if (pc == (unsigned long)ret_from_irq || pc == (unsigned long)ret_from_exception) { struct pt_regs *regs; if (*sp >= stack_page && *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) { regs = (struct pt_regs *)*sp; pc = regs->cp0_epc; if (__kernel_text_address(pc)) { *sp = regs->regs[29]; *ra = regs->regs[31]; return pc; } } return 0; } if (!kallsyms_lookup_size_offset(pc, &size, &ofs)) return 0; /* * Return ra if an exception occured at the first instruction */ if (unlikely(ofs == 0)) { pc = *ra; *ra = 0; return pc; } info.func = (void *)(pc - ofs); info.func_size = ofs; /* analyze from start to ofs */ leaf = get_frame_info(&info); if (leaf < 0) return 0; if (*sp < stack_page || *sp + info.frame_size > stack_page + THREAD_SIZE - 32) return 0; if (leaf) /* * For some extreme cases, get_frame_info() can * consider wrongly a nested function as a leaf * one. In that cases avoid to return always the * same value. */ pc = pc != *ra ? *ra : 0; else pc = ((unsigned long *)(*sp))[info.pc_offset]; *sp += info.frame_size; *ra = 0; return __kernel_text_address(pc) ? pc : 0; }
unsigned long notrace unwind_stack_by_address(unsigned long stack_page, unsigned long *sp, unsigned long pc, unsigned long *ra) { struct mips_frame_info info; unsigned long size, ofs; int leaf; extern void ret_from_irq(void); extern void ret_from_exception(void); if (!stack_page) return 0; /* */ if (pc == (unsigned long)ret_from_irq || pc == (unsigned long)ret_from_exception) { struct pt_regs *regs; if (*sp >= stack_page && *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) { regs = (struct pt_regs *)*sp; pc = regs->cp0_epc; if (__kernel_text_address(pc)) { *sp = regs->regs[29]; *ra = regs->regs[31]; return pc; } } return 0; } if (!kallsyms_lookup_size_offset(pc, &size, &ofs)) return 0; /* */ if (unlikely(ofs == 0)) { pc = *ra; *ra = 0; return pc; } info.func = (void *)(pc - ofs); info.func_size = ofs; /* */ leaf = get_frame_info(&info); if (leaf < 0) return 0; if (*sp < stack_page || *sp + info.frame_size > stack_page + THREAD_SIZE - 32) return 0; if (leaf) /* */ pc = pc != *ra ? *ra : 0; else pc = ((unsigned long *)(*sp))[info.pc_offset]; *sp += info.frame_size; *ra = 0; return __kernel_text_address(pc) ? pc : 0; }