/*----------------------------------------------------------------------------*/ static void probe_def_init(void) { probes[0].name = "insert_liboffs.exe probe"; probes[0].insert_loc.type = DR_PROBE_ADDR_LIB_OFFS; probes[0].insert_loc.lib_offs.library = "insert_liboffs.exe"; probes[0].insert_loc.lib_offs.offset = get_symbol_offset("insert_liboffs.map", "_doubler"); probes[0].callback_func.type = DR_PROBE_ADDR_LIB_OFFS; probes[0].callback_func.lib_offs.library = "../probe-api/insert_liboffs.client.dll"; /* probes[0].callback_func.lib_offs.library = "insert_liboffs.probe.dll"; */ probes[0].callback_func.lib_offs.offset = get_symbol_offset("insert_liboffs.client.map", "_doubler_probe"); }
const char *symbols_lookup(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, char *namebuf) { unsigned long i, low, high, mid; unsigned long symbol_end = 0; const struct virtual_region *region; namebuf[KSYM_NAME_LEN] = 0; namebuf[0] = 0; region = find_text_region(addr); if (!region) return NULL; if (region->symbols_lookup) return region->symbols_lookup(addr, symbolsize, offset, namebuf); /* do a binary search on the sorted symbols_addresses array */ low = 0; high = symbols_num_syms; while (high-low > 1) { mid = (low + high) / 2; if (symbols_address(mid) <= addr) low = mid; else high = mid; } /* search for the first aliased symbol. Aliased symbols are symbols with the same address */ while (low && symbols_address(low - 1) == symbols_address(low)) --low; /* Grab name */ symbols_expand_symbol(get_symbol_offset(low), namebuf); /* Search for next non-aliased symbol */ for (i = low + 1; i < symbols_num_syms; i++) { if (symbols_address(i) > symbols_address(low)) { symbol_end = symbols_address(i); break; } } /* if we found no next symbol, we use the end of the section */ if (!symbol_end) symbol_end = is_kernel_inittext(addr) ? (unsigned long)_einittext : (unsigned long)_etext; *symbolsize = symbol_end - symbols_address(low); *offset = addr - symbols_address(low); return namebuf; }
/* * Lookup an address * - modname is set to NULL if it's in the kernel. * - We guarantee that the returned name is valid until we reschedule even if. * It resides in a module. * - We also guarantee that modname will be valid until rescheduled. */ const char *kallsyms_lookup(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, char **modname, char *namebuf) { namebuf[KSYM_NAME_LEN - 1] = 0; namebuf[0] = 0; if (is_kernel_text(addr)) { unsigned long pos; pos = get_symbol_pos(addr, symbolsize, offset); /* Grab name */ kallsyms_expand_symbol(get_symbol_offset(pos), namebuf); if (modname) *modname = NULL; return namebuf; } /* moduled not yet supported in kallsyms */ return NULL; }
int xensyms_read(uint32_t *symnum, char *type, unsigned long *address, char *name) { /* * Symbols are most likely accessed sequentially so we remember position * from previous read. This can help us avoid the extra call to * get_symbol_offset(). */ static uint64_t next_symbol, next_offset; static DEFINE_SPINLOCK(symbols_mutex); if ( *symnum > symbols_num_syms ) return -ERANGE; if ( *symnum == symbols_num_syms ) { /* No more symbols */ name[0] = '\0'; return 0; } spin_lock(&symbols_mutex); if ( *symnum == 0 ) next_offset = next_symbol = 0; if ( next_symbol != *symnum ) /* Non-sequential access */ next_offset = get_symbol_offset(*symnum); *type = symbols_get_symbol_type(next_offset); next_offset = symbols_expand_symbol(next_offset, name); *address = symbols_address(*symnum); next_symbol = ++*symnum; spin_unlock(&symbols_mutex); return 0; }
static void command_get_context(char * token, Channel * c) { int err = 0; char id[256]; Symbol sym; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); if (id2symbol(id, &sym) < 0) err = errno; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err == 0) { char * name = NULL; int type_class = TYPE_CLASS_UNKNOWN; Symbol type; size_t size = 0; void * value = NULL; unsigned long length = 0; unsigned long offset = 0; ContextAddress address = 0; int frame = STACK_NO_FRAME; /* TODO: symbol frame */ write_stream(&c->out, '{'); json_write_string(&c->out, "ID"); write_stream(&c->out, ':'); json_write_string(&c->out, id); write_stream(&c->out, ','); json_write_string(&c->out, "ExeID"); write_stream(&c->out, ':'); json_write_string(&c->out, container_id(sym.ctx)); write_stream(&c->out, ','); if (get_symbol_name(&sym, &name) == 0 && name != NULL) { json_write_string(&c->out, "Name"); write_stream(&c->out, ':'); json_write_string(&c->out, name); write_stream(&c->out, ','); loc_free(name); } if (get_symbol_type_class(&sym, &type_class) == 0 && type_class != TYPE_CLASS_UNKNOWN) { json_write_string(&c->out, "TypeClass"); write_stream(&c->out, ':'); json_write_long(&c->out, type_class); write_stream(&c->out, ','); } if (get_symbol_type(&sym, &type) == 0) { json_write_string(&c->out, "TypeID"); write_stream(&c->out, ':'); json_write_string(&c->out, symbol2id(&type)); write_stream(&c->out, ','); } if (get_symbol_base_type(&sym, &type) == 0) { json_write_string(&c->out, "BaseTypeID"); write_stream(&c->out, ':'); json_write_string(&c->out, symbol2id(&type)); write_stream(&c->out, ','); } if (get_symbol_index_type(&sym, &type) == 0) { json_write_string(&c->out, "IndexTypeID"); write_stream(&c->out, ':'); json_write_string(&c->out, symbol2id(&type)); write_stream(&c->out, ','); } if (get_symbol_size(&sym, frame, &size) == 0) { json_write_string(&c->out, "Size"); write_stream(&c->out, ':'); json_write_long(&c->out, size); write_stream(&c->out, ','); } if (get_symbol_length(&sym, frame, &length) == 0) { json_write_string(&c->out, "Length"); write_stream(&c->out, ':'); json_write_long(&c->out, length); write_stream(&c->out, ','); } if (sym.sym_class == SYM_CLASS_REFERENCE) { if (get_symbol_offset(&sym, &offset) == 0) { json_write_string(&c->out, "Offset"); write_stream(&c->out, ':'); json_write_long(&c->out, offset); write_stream(&c->out, ','); } if (get_symbol_address(&sym, frame, &address) == 0) { json_write_string(&c->out, "Address"); write_stream(&c->out, ':'); json_write_long(&c->out, address); write_stream(&c->out, ','); } } if (sym.sym_class == SYM_CLASS_VALUE && get_symbol_value(&sym, &value, &size) == 0) { json_write_string(&c->out, "Value"); write_stream(&c->out, ':'); json_write_binary(&c->out, value, size); write_stream(&c->out, ','); } json_write_string(&c->out, "Class"); write_stream(&c->out, ':'); json_write_long(&c->out, sym.sym_class); write_stream(&c->out, '}'); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
/** * Lookup the symbol name corresponding to a kernel address */ const char *kallsyms_lookup(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, char *namebuf) { unsigned long i, low, high, mid; /* This kernel should never had been booted. */ BUG_ON(!kallsyms_addresses); namebuf[KSYM_NAME_LEN] = 0; namebuf[0] = 0; if ((all_var && is_kernel(addr)) || (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) || is_kernel_extratext(addr)))) { unsigned long symbol_end = 0; /* do a binary search on the sorted kallsyms_addresses array */ low = 0; high = kallsyms_num_syms; while (high-low > 1) { mid = (low + high) / 2; if (kallsyms_addresses[mid] <= addr) low = mid; else high = mid; } /* search for the first aliased symbol. Aliased symbols are symbols with the same address */ while (low && kallsyms_addresses[low - 1] == kallsyms_addresses[low]) --low; /* Grab name */ kallsyms_expand_symbol(get_symbol_offset(low), namebuf); /* Search for next non-aliased symbol */ for (i = low + 1; i < kallsyms_num_syms; i++) { if (kallsyms_addresses[i] > kallsyms_addresses[low]) { symbol_end = kallsyms_addresses[i]; break; } } /* if we found no next symbol, we use the end of the section */ if (!symbol_end) { if (is_kernel_inittext(addr)) symbol_end = (unsigned long)_einittext; else symbol_end = (all_var) ? (unsigned long)_end : (unsigned long)_etext; } if (symbolsize) *symbolsize = symbol_end - kallsyms_addresses[low]; if (offset) *offset = addr - kallsyms_addresses[low]; return namebuf; } return NULL; }