void __init check_iommu_entries(struct iommu_table_entry *start, struct iommu_table_entry *finish) { struct iommu_table_entry *p, *q, *x; char sym_p[KSYM_SYMBOL_LEN]; char sym_q[KSYM_SYMBOL_LEN]; /* Simple cyclic dependency checker. */ for (p = start; p < finish; p++) { q = find_dependents_of(start, finish, p); x = find_dependents_of(start, finish, q); if (p == x) { sprint_symbol(sym_p, (unsigned long)p->detect); sprint_symbol(sym_q, (unsigned long)q->detect); printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %s depends" \ " on %s and vice-versa. BREAKING IT.\n", sym_p, sym_q); /* Heavy handed way..*/ x->depend = 0; } } for (p = start; p < finish; p++) { q = find_dependents_of(p, finish, p); if (q && q > p) { sprint_symbol(sym_p, (unsigned long)p->detect); sprint_symbol(sym_q, (unsigned long)q->detect); printk(KERN_ERR "EXECUTION ORDER INVALID! %s "\ "should be called before %s!\n", sym_p, sym_q); } } }
void trace_boot_call(struct boot_trace_call *bt, initcall_t fn) { struct ring_buffer_event *event; struct trace_boot_call *entry; struct trace_array *tr = boot_trace; if (!tr || !pre_initcalls_finished) return; /* Get its name now since this function could * disappear because it is in the .init section. */ sprint_symbol(bt->func, (unsigned long)fn); preempt_disable(); event = trace_buffer_lock_reserve(tr, TRACE_BOOT_CALL, sizeof(*entry), 0, 0); if (!event) goto out; entry = ring_buffer_event_data(event); entry->boot_call = *bt; trace_buffer_unlock_commit(tr, event, 0, 0); out: preempt_enable(); }
/* this function may be time consuming, move out from table set/get? */ ktap_str_t *kp_obj_kstack2str(ktap_state_t *ks, uint16_t depth, uint16_t skip) { struct stack_trace trace; unsigned long *bt; char *btstr, *p; int i; bt = kp_this_cpu_print_buffer(ks); /* use print percpu buffer */ trace.nr_entries = 0; trace.skip = skip; trace.max_entries = depth; trace.entries = (unsigned long *)(bt + 1); save_stack_trace(&trace); /* convert backtrace to string */ p = btstr = kp_this_cpu_temp_buffer(ks); for (i = 0; i < trace.nr_entries; i++) { unsigned long addr = trace.entries[i]; if (addr == ULONG_MAX) break; p += sprint_symbol(p, addr); *p++ = '\n'; } return kp_str_new(ks, btstr, p - btstr); }
void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn) { struct ftrace_event_call *call = &event_boot_ret; struct ring_buffer_event *event; struct ring_buffer *buffer; struct trace_boot_ret *entry; struct trace_array *tr = boot_trace; if (!tr || !pre_initcalls_finished) return; sprint_symbol(bt->func, (unsigned long)fn); preempt_disable(); buffer = tr->buffer; event = trace_buffer_lock_reserve(buffer, TRACE_BOOT_RET, sizeof(*entry), 0, 0); if (!event) goto out; entry = ring_buffer_event_data(event); entry->boot_ret = *bt; if (!filter_check_discard(call, entry, buffer, event)) trace_buffer_unlock_commit(buffer, event, 0, 0); out: preempt_enable(); }
void trace_boot(struct boot_trace *it, initcall_t fn) { struct ring_buffer_event *event; struct trace_boot *entry; struct trace_array_cpu *data; unsigned long irq_flags; struct trace_array *tr = boot_trace; if (!trace_boot_enabled) return; /* Get its name now since this function could * disappear because it is in the .init section. */ sprint_symbol(it->func, (unsigned long)fn); preempt_disable(); data = tr->data[smp_processor_id()]; event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry), &irq_flags); if (!event) goto out; entry = ring_buffer_event_data(event); tracing_generic_entry_update(&entry->ent, 0, 0); entry->ent.type = TRACE_BOOT; entry->initcall = *it; ring_buffer_unlock_commit(tr->buffer, event, irq_flags); trace_wake_up(); out: preempt_enable(); }
static int lstats_show(struct seq_file *m, void *v) { int i; seq_puts(m, "Latency Top version : v0.1\n"); for (i = 0; i < MAXLR; i++) { if (latency_record[i].backtrace[0]) { int q; seq_printf(m, "%i %lu %lu ", latency_record[i].count, latency_record[i].time, latency_record[i].max); for (q = 0; q < LT_BACKTRACEDEPTH; q++) { char sym[KSYM_SYMBOL_LEN]; char *c; if (!latency_record[i].backtrace[q]) break; if (latency_record[i].backtrace[q] == ULONG_MAX) break; sprint_symbol(sym, latency_record[i].backtrace[q]); c = strchr(sym, '+'); if (c) *c = 0; seq_printf(m, "%s ", sym); } seq_printf(m, "\n"); } } return 0; }
void ltt_dump_sys_call_table(void *call_data) { int i; char namebuf[KSYM_NAME_LEN]; for (i = 0; i < __NR_syscall_max + 1; i++) { sprint_symbol(namebuf, sys_call_table[i]); __trace_mark(0, syscall_state, sys_call_table, call_data, "id %d address %p symbol %s", i, (void*)sys_call_table[i], namebuf); } }
static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int precision, int flags) { unsigned long value = (unsigned long) ptr; #ifdef CONFIG_KALLSYMS char sym[KSYM_SYMBOL_LEN]; sprint_symbol(sym, value); return string(buf, end, sym, field_width, precision, flags); #else field_width = 2*sizeof(void *); flags |= SPECIAL | SMALL | ZEROPAD; return number(buf, end, value, 16, field_width, precision, flags); #endif }
void warn_on_slowpath(const char *file, int line) { char function[KSYM_SYMBOL_LEN]; unsigned long caller = (unsigned long) __builtin_return_address(0); sprint_symbol(function, caller); printk(KERN_WARNING "------------[ cut here ]------------\n"); printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file, line, function); print_modules(); dump_stack(); print_oops_end_marker(); }
void ltt_dump_idt_table(void *call_data) { int i; char namebuf[KSYM_NAME_LEN]; for (i = 0; i < IDT_ENTRIES; i++) { unsigned long address = gate_offset(idt_table[i]); sprint_symbol(namebuf, address); __trace_mark(0, irq_state, idt_table, call_data, "irq %d address %p symbol %s", i, (void *)address, namebuf); } }
void exynos_cs_show_pcval(void) { unsigned long flags; unsigned int cpu, iter; unsigned int val = 0; if (exynos_cs_stat < 0) return; spin_lock_irqsave(&lock, flags); for (iter = 0; iter < ITERATION; iter++) { for (cpu = 0; cpu < NR_CPUS; cpu++) { void __iomem *base = (void *) exynos_cs_base[cpu]; if (base == NULL || !exynos_core_status(cpu)) { exynos_cs_base[cpu] = 0; continue; } /* Release OSlock */ writel(0x1, base + CS_OSLOCK); /* Read current PC value */ val = __raw_readl(base + CS_PC_VAL); if (cpu >= 4) { /* The PCSR of A15 shoud be substracted 0x8 from * curretnly PCSR value */ val -= 0x8; } exynos_cs_pc[cpu][iter] = val; } } spin_unlock_irqrestore(&lock, flags); for (cpu = 0; cpu < NR_CPUS; cpu++) { if (exynos_cs_base[cpu] == 0) continue; pr_err("CPU[%d] saved pc value\n", cpu); for (iter = 0; iter < ITERATION; iter++) { char buf[KSYM_SYMBOL_LEN]; sprint_symbol(buf, exynos_cs_pc[cpu][iter]); pr_err(" 0x%08x : %s\n", exynos_cs_pc[cpu][iter], buf); } } }
int __init sprint_symbol_init(void) { char buffer[KSYM_SYMBOL_LEN]; //声明一个文本缓冲区 int ret; //接收sprint_symbol( )函数返回值 unsigned long address; //表示符号地址 char * name; //模块名字 struct module * fmodule = NULL; //指向一个模块的指针 address = (unsigned long) __builtin_return_address(0); //当前函数的返回地址 ret = sprint_symbol( buffer , address ); printk("<0>ret: %d\n", ret ); //输出返回值 printk("<0>buffer: %s\n", buffer ); //输出文本缓冲区 buffer 的内容 printk("<0>\n"); name = "vboxvideo"; fmodule = find_module( name ); //查找模块名为 "vboxvideo" 的模块 if( fmodule != NULL ) { printk("<0>fmodule->name: %s\n",fmodule->name); address = (unsigned long)fmodule->module_core; //将模块的内存起始地址赋值给 address ret = sprint_symbol( buffer , address ); printk("<0>ret: %d\n", ret ); printk("<0>buffer: %s\n", buffer ); } printk("<0>\n"); address = (unsigned long)a_symbol + 5; //将当前模块中符号 a_symbol 的地址加上偏移量 5 赋值给 address ret = sprint_symbol( buffer , address ); printk("<0>ret: %d\n", ret ); printk("<0>buffer: %s\n", buffer ); return 0; }
void sprint_gvector(LispObj o, int depth) { LispObj header = header_of(o); unsigned elements = header_element_count(header), subtag = header_subtag(header); switch(subtag) { case subtag_function: sprint_function(o, depth); break; case subtag_symbol: sprint_symbol(o); break; case subtag_struct: case subtag_istruct: add_c_string("#<"); sprint_lisp_object(deref(o,1), depth); add_c_string(" @"); sprint_unsigned_hex(o); add_c_string(">"); break; case subtag_simple_vector: { int i; add_c_string("#("); for(i = 1; i <= elements; i++) { if (i > 1) { add_char(' '); } sprint_lisp_object(deref(o, i), depth); } add_char(')'); break; } default: sprint_random_vector(o, subtag, elements); break; } }
void warn_slowpath(const char *file, int line, const char *fmt, ...) { va_list args; char function[KSYM_SYMBOL_LEN]; unsigned long caller = (unsigned long)__builtin_return_address(0); sprint_symbol(function, caller); printk(KERN_WARNING "------------[ cut here ]------------\n"); printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file, line, function); va_start(args, fmt); vprintk(fmt, args); va_end(args); print_modules(); dump_stack(); print_oops_end_marker(); add_taint(TAINT_WARN); }
static int lstats_show(struct seq_file *m, void *v) { int i; seq_puts(m, "Latency Top version : v0.1\n"); for (i = 0; i < MAXLR; i++) { <<<<<<< HEAD struct latency_record *lr = &latency_record[i]; if (lr->backtrace[0]) { int q; seq_printf(m, "%i %lu %lu", lr->count, lr->time, lr->max); for (q = 0; q < LT_BACKTRACEDEPTH; q++) { unsigned long bt = lr->backtrace[q]; if (!bt) break; if (bt == ULONG_MAX) break; seq_printf(m, " %ps", (void *)bt); ======= if (latency_record[i].backtrace[0]) { int q; seq_printf(m, "%i %lu %lu ", latency_record[i].count, latency_record[i].time, latency_record[i].max); for (q = 0; q < LT_BACKTRACEDEPTH; q++) { char sym[KSYM_SYMBOL_LEN]; char *c; if (!latency_record[i].backtrace[q]) break; if (latency_record[i].backtrace[q] == ULONG_MAX) break; sprint_symbol(sym, latency_record[i].backtrace[q]); c = strchr(sym, '+'); if (c) *c = 0; seq_printf(m, "%s ", sym); >>>>>>> 296c66da8a02d52243f45b80521febece5ed498a }
/* * fnic_get_trace_data - Copy trace buffer to a memory file * @fnic_dbgfs_t: pointer to debugfs trace buffer * * Description: * This routine gathers the fnic trace debugfs data from the fnic_trace_data_t * buffer and dumps it to fnic_dbgfs_t. It will start at the rd_idx entry in * the log and process the log until the end of the buffer. Then it will gather * from the beginning of the log and process until the current entry @wr_idx. * * Return Value: * This routine returns the amount of bytes that were dumped into fnic_dbgfs_t */ int fnic_get_trace_data(fnic_dbgfs_t *fnic_dbgfs_prt) { int rd_idx; int wr_idx; int len = 0; unsigned long flags; char str[KSYM_SYMBOL_LEN]; struct timespec val; fnic_trace_data_t *tbp; spin_lock_irqsave(&fnic_trace_lock, flags); rd_idx = fnic_trace_entries.rd_idx; wr_idx = fnic_trace_entries.wr_idx; if (wr_idx < rd_idx) { while (1) { /* Start from read index @rd_idx */ tbp = (fnic_trace_data_t *) fnic_trace_entries.page_offset[rd_idx]; if (!tbp) { spin_unlock_irqrestore(&fnic_trace_lock, flags); return 0; } /* Convert function pointer to function name */ if (sizeof(unsigned long) < 8) { sprint_symbol(str, tbp->fnaddr.low); jiffies_to_timespec(tbp->timestamp.low, &val); } else { sprint_symbol(str, tbp->fnaddr.val); jiffies_to_timespec(tbp->timestamp.val, &val); } /* * Dump trace buffer entry to memory file * and increment read index @rd_idx */ len += snprintf(fnic_dbgfs_prt->buffer + len, (trace_max_pages * PAGE_SIZE * 3) - len, "%16lu.%16lu %-50s %8x %8x %16llx %16llx " "%16llx %16llx %16llx\n", val.tv_sec, val.tv_nsec, str, tbp->host_no, tbp->tag, tbp->data[0], tbp->data[1], tbp->data[2], tbp->data[3], tbp->data[4]); rd_idx++; /* * If rd_idx is reached to maximum trace entries * then move rd_idx to zero */ if (rd_idx > (fnic_max_trace_entries-1)) rd_idx = 0; /* * Continure dumpping trace buffer entries into * memory file till rd_idx reaches write index */ if (rd_idx == wr_idx) break; } } else if (wr_idx > rd_idx) { while (1) { /* Start from read index @rd_idx */ tbp = (fnic_trace_data_t *) fnic_trace_entries.page_offset[rd_idx]; if (!tbp) { spin_unlock_irqrestore(&fnic_trace_lock, flags); return 0; } /* Convert function pointer to function name */ if (sizeof(unsigned long) < 8) { sprint_symbol(str, tbp->fnaddr.low); jiffies_to_timespec(tbp->timestamp.low, &val); } else { sprint_symbol(str, tbp->fnaddr.val); jiffies_to_timespec(tbp->timestamp.val, &val); } /* * Dump trace buffer entry to memory file * and increment read index @rd_idx */ len += snprintf(fnic_dbgfs_prt->buffer + len, (trace_max_pages * PAGE_SIZE * 3) - len, "%16lu.%16lu %-50s %8x %8x %16llx %16llx " "%16llx %16llx %16llx\n", val.tv_sec, val.tv_nsec, str, tbp->host_no, tbp->tag, tbp->data[0], tbp->data[1], tbp->data[2], tbp->data[3], tbp->data[4]); rd_idx++; /* * Continue dumpping trace buffer entries into * memory file till rd_idx reaches write index */ if (rd_idx == wr_idx) break; } } spin_unlock_irqrestore(&fnic_trace_lock, flags); return len; }
void sprint_lisp_object(LispObj o, int depth) { if (--depth < 0) { add_char('#'); } else { switch (fulltag_of(o)) { case fulltag_even_fixnum: case fulltag_odd_fixnum: sprint_signed_decimal(unbox_fixnum(o)); break; #ifdef X8664 case fulltag_immheader_0: case fulltag_immheader_1: case fulltag_immheader_2: case fulltag_nodeheader_0: case fulltag_nodeheader_1: #else case fulltag_immheader: case fulltag_nodeheader: #endif add_c_string("#<header ? "); sprint_unsigned_hex(o); add_c_string(">"); break; #ifdef X8664 case fulltag_imm_0: case fulltag_imm_1: #else case fulltag_imm: #endif if (o == unbound) { add_c_string("#<Unbound>"); } else { if (header_subtag(o) == subtag_character) { unsigned c = (o >> charcode_shift); add_c_string("#\\"); if ((c >= ' ') && (c < 0x7f)) { add_char(c); } else { sprintf(numbuf, "%#o", c); add_c_string(numbuf); } #ifdef X8664 } else if (header_subtag(o) == subtag_single_float) { LispObj xx = o; float f = ((float *)&xx)[1]; sprintf(numbuf, "%f", f); add_c_string(numbuf); #endif } else { add_c_string("#<imm "); sprint_unsigned_hex(o); add_c_string(">"); } } break; #ifdef X8664 case fulltag_nil: #endif case fulltag_cons: sprint_list(o, depth); break; case fulltag_misc: sprint_vector(o, depth); break; #ifdef X8664 case fulltag_symbol: sprint_symbol(o); break; case fulltag_function: sprint_function(o, depth); break; #endif #ifdef X8664 case fulltag_tra_0: case fulltag_tra_1: #else case fulltag_tra: #endif sprint_tra(o,depth); break; }