bool symbol_manager::query_system_for_address(FPTR address) { // need at least the sym_from_addr API if (!m_sym_from_addr) return false; BYTE info_buffer[sizeof(SYMBOL_INFO) + 256] = { 0 }; SYMBOL_INFO &info = *reinterpret_cast<SYMBOL_INFO *>(&info_buffer[0]); DWORD64 displacement; // even through the struct says TCHAR, we actually get back an ANSI string here info.SizeOfStruct = sizeof(info); info.MaxNameLen = sizeof(info_buffer) - sizeof(info); if ((*m_sym_from_addr)(m_process, address, &displacement, &info)) { // try to get source info as well; again we are returned an ANSI string IMAGEHLP_LINE64 lineinfo = { sizeof(lineinfo) }; DWORD linedisp; if (m_sym_get_line_from_addr_64 && (*m_sym_get_line_from_addr_64)(m_process, address, &linedisp, &lineinfo)) format_symbol(info.Name, displacement, lineinfo.FileName, lineinfo.LineNumber); else format_symbol(info.Name, displacement); // set the last base m_last_base = address - displacement; return true; } return false; }
std::string format_address_win32(const void* addr) const { if (!dbghelp.initialized()) return format_address_fallback(addr); DWORD64 symbol_info_buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME]; const auto symbol_info = reinterpret_cast<SYMBOL_INFO*>(symbol_info_buf); symbol_info->SizeOfStruct = sizeof(SYMBOL_INFO); symbol_info->MaxNameLen = MAX_SYM_NAME; IMAGEHLP_MODULE64 module_info; module_info.SizeOfStruct = sizeof(IMAGEHLP_MODULE64); DWORD64 symbol_offset; const auto symbol_resolved = SymFromAddr( GetCurrentProcess(), reinterpret_cast<DWORD64>(addr), &symbol_offset, symbol_info); if (symbol_resolved) { const auto module_resolved = SymGetModuleInfo64( GetCurrentProcess(), symbol_info->ModBase, &module_info); if (module_resolved) { return format_symbol( module_info.ModuleName, symbol_info->Name, reinterpret_cast<const void*>(symbol_offset)); } else { return format_symbol(symbol_info->Name, addr); } } else { const auto module_resolved = SymGetModuleInfo64( GetCurrentProcess(), reinterpret_cast<DWORD64>(addr), &module_info); if (module_resolved) { const auto module_offset = reinterpret_cast<const char*>(addr) - module_info.BaseOfImage; return format_module(module_info.ModuleName, module_offset); } else { return format_address_fallback(addr); } } }
void simple_format ( MPL *mpl, SET *set, /* not changed */ MEMBER *memb, /* modified */ SLICE *slice /* not changed */ ) { TUPLE *tuple; SLICE *temp; SYMBOL *sym, *with = NULL; insist(set != NULL); insist(memb != NULL); insist(slice != NULL); insist(set->dimen == slice_dimen(mpl, slice)); insist(memb->value.set->dim == set->dimen); if (slice_arity(mpl, slice) > 0) insist(is_symbol(mpl)); /* read symbols and construct complete n-tuple */ tuple = create_tuple(mpl); for (temp = slice; temp != NULL; temp = temp->next) { if (temp->sym == NULL) { /* substitution is needed; read symbol */ if (!is_symbol(mpl)) { int lack = slice_arity(mpl, temp); /* with cannot be null due to assertion above */ insist(with != NULL); if (lack == 1) error(mpl, "one item missing in data group beginning " "with %s", format_symbol(mpl, with)); else error(mpl, "%d items missing in data group beginning " "with %s", lack, format_symbol(mpl, with)); } sym = read_symbol(mpl); if (with == NULL) with = sym; } else { /* copy symbol from the slice */ sym = copy_symbol(mpl, temp->sym); } /* append the symbol to the n-tuple */ tuple = expand_tuple(mpl, tuple, sym); /* skip optional comma *between* <symbols> */ if (temp->next != NULL && mpl->token == T_COMMA) get_token(mpl /* , */); } /* add constructed n-tuple to elemental set */ check_then_add(mpl, memb->value.set, tuple); return; }
static std::string format_symbol( const std::string& module_name, const std::string& symbol_name, const void* offset = nullptr) { return format_symbol(module_name + "!" + symbol_name, offset); }
void plain_format ( MPL *mpl, PARAMETER *par, /* not changed */ SLICE *slice /* not changed */ ) { TUPLE *tuple; SLICE *temp; SYMBOL *sym, *with = NULL; insist(par != NULL); insist(par->dim == slice_dimen(mpl, slice)); insist(is_symbol(mpl)); /* read symbols and construct complete subscript list */ tuple = create_tuple(mpl); for (temp = slice; temp != NULL; temp = temp->next) { if (temp->sym == NULL) { /* substitution is needed; read symbol */ if (!is_symbol(mpl)) { int lack = slice_arity(mpl, temp) + 1; insist(with != NULL); insist(lack > 1); error(mpl, "%d items missing in data group beginning wit" "h %s", lack, format_symbol(mpl, with)); } sym = read_symbol(mpl); if (with == NULL) with = sym; } else { /* copy symbol from the slice */ sym = copy_symbol(mpl, temp->sym); } /* append the symbol to the subscript list */ tuple = expand_tuple(mpl, tuple, sym); /* skip optional comma */ if (mpl->token == T_COMMA) get_token(mpl /* , */); } /* read value and assign it to new parameter member */ if (!is_symbol(mpl)) { insist(with != NULL); error(mpl, "one item missing in data group beginning with %s", format_symbol(mpl, with)); } read_value(mpl, par, tuple); return; }
void symbol_manager::scan_file_for_address(FPTR address, bool create_cache) { bool is_symfile = false; FILE *srcfile = nullptr; #ifdef __GNUC__ // see if we have a symbol file (gcc only) srcfile = fopen(m_symfile.c_str(), "r"); is_symfile = (srcfile != nullptr); #endif // if not, see if we have a map file if (srcfile == nullptr) srcfile = fopen(m_mapfile.c_str(), "r"); // if not, fail if (srcfile == nullptr) return; // reset the best info std::string best_symbol; FPTR best_addr = 0; // parse the file, looking for valid entries std::string symbol; char line[1024]; while (fgets(line, sizeof(line) - 1, srcfile)) { // parse the line looking for an interesting symbol FPTR addr = 0; bool valid = is_symfile ? parse_sym_line(line, addr, symbol) : parse_map_line(line, addr, symbol); // if we got one, see if this is the best if (valid) { // if this is the best one so far, remember it if (addr <= address && addr > best_addr) { best_addr = addr; best_symbol = symbol; } // also create a cache entry if we can if (create_cache) m_cache.push_back(std::make_unique<cache_entry>(addr, symbol.c_str())); } } // close the file fclose(srcfile); // format the symbol and remember the last base format_symbol(best_symbol.c_str(), address - best_addr); m_last_base = best_addr; }
static t_atom* format_atoms(int ac, t_atom* av) { int i; for(i = 0; i < ac; i++) { if(atom_gettype(av+i) == A_SYMBOL) { atom_setsym(av+i, format_symbol(atom_getsymbol(av+i))); } } return av; }
void symbol_manager::scan_cache_for_address(FPTR address) { // reset the best info std::string best_symbol; FPTR best_addr = 0; // walk the cache, looking for valid entries for (auto &entry : m_cache) // if this is the best one so far, remember it if (entry->m_address <= address && entry->m_address > best_addr) { best_addr = entry->m_address; best_symbol = entry->m_name; } // format the symbol and remember the last base format_symbol(best_symbol.c_str(), address - best_addr); m_last_base = best_addr; }
void tabbing_format ( MPL *mpl, SYMBOL *altval /* not changed */ ) { SET *set = NULL; PARAMETER *par; SLICE *list, *col; TUPLE *tuple; int next_token, j, dim = 0; char *last_name = NULL; /* read the optional <prefix> */ if (is_symbol(mpl)) { get_token(mpl /* <symbol> */); next_token = mpl->token; unget_token(mpl /* <symbol> */); if (next_token == T_COLON) { /* select the set to saturate it with data */ set = select_set(mpl, mpl->image); /* the set must be simple (i.e. not set of sets) */ if (set->dim != 0) error(mpl, "%s must be a simple set", set->name); /* and must not be defined yet */ if (set->array->head != NULL) error(mpl, "%s already defined", set->name); /* add new (the only) member to the set and assign it empty elemental set */ add_member(mpl, set->array, NULL)->value.set = create_elemset(mpl, set->dimen); last_name = set->name, dim = set->dimen; get_token(mpl /* <symbol> */); insist(mpl->token == T_COLON); get_token(mpl /* : */); } } /* read the table heading that contains parameter names */ list = create_slice(mpl); while (mpl->token != T_ASSIGN) { /* there must be symbolic name of parameter */ if (!is_symbol(mpl)) error(mpl, "parameter name or := missing where expected"); /* select the parameter to saturate it with data */ par = select_parameter(mpl, mpl->image); /* the parameter must be subscripted */ if (par->dim == 0) error(mpl, "%s not a subscripted parameter", mpl->image); /* the set (if specified) and all the parameters in the data block must have identical dimension */ if (dim != 0 && par->dim != dim) { insist(last_name != NULL); error(mpl, "%s has dimension %d while %s has dimension %d", last_name, dim, par->name, par->dim); } /* set default value for the parameter (if specified) */ if (altval != NULL) set_default(mpl, par, copy_symbol(mpl, altval)); /* append the parameter to the column list */ list = expand_slice(mpl, list, (SYMBOL *)par); last_name = par->name, dim = par->dim; get_token(mpl /* <symbol> */); /* skip optional comma */ if (mpl->token == T_COMMA) get_token(mpl /* , */); } if (slice_dimen(mpl, list) == 0) error(mpl, "at least one parameter name required"); get_token(mpl /* := */); /* skip optional comma */ if (mpl->token == T_COMMA) get_token(mpl /* , */); /* read rows that contain tabbing data */ while (is_symbol(mpl)) { /* read subscript list */ tuple = create_tuple(mpl); for (j = 1; j <= dim; j++) { /* read j-th subscript */ if (!is_symbol(mpl)) { int lack = slice_dimen(mpl, list) + dim - j + 1; insist(tuple != NULL); insist(lack > 1); error(mpl, "%d items missing in data group beginning wit" "h %s", lack, format_symbol(mpl, tuple->sym)); } /* read and append j-th subscript to the n-tuple */ tuple = expand_tuple(mpl, tuple, read_symbol(mpl)); /* skip optional comma *between* <symbols> */ if (j < dim && mpl->token == T_COMMA) get_token(mpl /* , */); } /* if the set is specified, add to it new n-tuple, which is a copy of the subscript list just read */ if (set != NULL) check_then_add(mpl, set->array->head->value.set, copy_tuple(mpl, tuple)); /* skip optional comma between <symbol> and <value> */ if (mpl->token == T_COMMA) get_token(mpl /* , */); /* read values accordingly to the column list */ for (col = list; col != NULL; col = col->next) { /* if the token is single point, no value is provided */ if (is_literal(mpl, ".")) { get_token(mpl /* . */); continue; } /* read value and assign it to new parameter member */ if (!is_symbol(mpl)) { int lack = slice_dimen(mpl, col); insist(tuple != NULL); if (lack == 1) error(mpl, "one item missing in data group beginning " "with %s", format_symbol(mpl, tuple->sym)); else error(mpl, "%d items missing in data group beginning " "with %s", lack, format_symbol(mpl, tuple->sym)); } read_value(mpl, (PARAMETER *)col->sym, copy_tuple(mpl, tuple)); /* skip optional comma preceding the next value */ if (col->next != NULL && mpl->token == T_COMMA) get_token(mpl /* , */); } /* delete the original subscript list */ delete_tuple(mpl, tuple); /* skip optional comma (only if there is next data group) */ if (mpl->token == T_COMMA) { get_token(mpl /* , */); if (!is_symbol(mpl)) unget_token(mpl /* , */); } } /* delete the column list (it contains parameters, not symbols, so nullify it before) */ for (col = list; col != NULL; col = col->next) col->sym = NULL; delete_slice(mpl, list); return; }
void tabular_format ( MPL *mpl, PARAMETER *par, /* not changed */ SLICE *slice, /* not changed */ int tr ) { SLICE *list, *col, *temp; TUPLE *tuple; SYMBOL *row; insist(par != NULL); insist(par->dim == slice_dimen(mpl, slice)); insist(slice_arity(mpl, slice) == 2); /* read the table heading that contains column symbols (the table may have no columns) */ list = create_slice(mpl); while (mpl->token != T_ASSIGN) { /* read column symbol and append it to the column list */ if (!is_symbol(mpl)) error(mpl, "number, symbol, or := missing where expected"); list = expand_slice(mpl, list, read_symbol(mpl)); } get_token(mpl /* := */); /* read zero or more rows that contain tabular data */ while (is_symbol(mpl)) { /* read row symbol (if the table has no columns, these symbols are just ignored) */ row = read_symbol(mpl); /* read values accordingly to the column list */ for (col = list; col != NULL; col = col->next) { int which = 0; /* if the token is single point, no value is provided */ if (is_literal(mpl, ".")) { get_token(mpl /* . */); continue; } /* construct complete subscript list */ tuple = create_tuple(mpl); for (temp = slice; temp != NULL; temp = temp->next) { if (temp->sym == NULL) { /* substitution is needed */ switch (++which) { case 1: /* substitute in the first null position */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, tr ? col->sym : row)); break; case 2: /* substitute in the second null position */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, tr ? row : col->sym)); break; default: insist(which != which); } } else { /* copy symbol from the slice */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, temp->sym)); } } insist(which == 2); /* read value and assign it to new parameter member */ if (!is_symbol(mpl)) { int lack = slice_dimen(mpl, col); if (lack == 1) error(mpl, "one item missing in data group beginning " "with %s", format_symbol(mpl, row)); else error(mpl, "%d items missing in data group beginning " "with %s", lack, format_symbol(mpl, row)); } read_value(mpl, par, tuple); } /* delete the row symbol */ delete_symbol(mpl, row); } /* delete the column list */ delete_slice(mpl, list); return; }
void matrix_format ( MPL *mpl, SET *set, /* not changed */ MEMBER *memb, /* modified */ SLICE *slice, /* not changed */ int tr ) { SLICE *list, *col, *temp; TUPLE *tuple; SYMBOL *row; insist(set != NULL); insist(memb != NULL); insist(slice != NULL); insist(set->dimen == slice_dimen(mpl, slice)); insist(memb->value.set->dim == set->dimen); insist(slice_arity(mpl, slice) == 2); /* read the matrix heading that contains column symbols (there may be no columns at all) */ list = create_slice(mpl); while (mpl->token != T_ASSIGN) { /* read column symbol and append it to the column list */ if (!is_symbol(mpl)) error(mpl, "number, symbol, or := missing where expected"); list = expand_slice(mpl, list, read_symbol(mpl)); } get_token(mpl /* := */); /* read zero or more rows that contain matrix data */ while (is_symbol(mpl)) { /* read row symbol (if the matrix has no columns, row symbols are just ignored) */ row = read_symbol(mpl); /* read the matrix row accordingly to the column list */ for (col = list; col != NULL; col = col->next) { int which = 0; /* check indicator */ if (is_literal(mpl, "+")) ; else if (is_literal(mpl, "-")) { get_token(mpl /* - */); continue; } else { int lack = slice_dimen(mpl, col); if (lack == 1) error(mpl, "one item missing in data group beginning " "with %s", format_symbol(mpl, row)); else error(mpl, "%d items missing in data group beginning " "with %s", lack, format_symbol(mpl, row)); } /* construct complete n-tuple */ tuple = create_tuple(mpl); for (temp = slice; temp != NULL; temp = temp->next) { if (temp->sym == NULL) { /* substitution is needed */ switch (++which) { case 1: /* substitute in the first null position */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, tr ? col->sym : row)); break; case 2: /* substitute in the second null position */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, tr ? row : col->sym)); break; default: insist(which != which); } } else { /* copy symbol from the slice */ tuple = expand_tuple(mpl, tuple, copy_symbol(mpl, temp->sym)); } } insist(which == 2); /* add constructed n-tuple to elemental set */ check_then_add(mpl, memb->value.set, tuple); get_token(mpl /* + */); } /* delete the row symbol */ delete_symbol(mpl, row); } /* delete the column list */ delete_slice(mpl, list); return; }