diff options
Diffstat (limited to 'src/usr/hwpf/ifcompiler/initSymbols.C')
-rwxr-xr-x | src/usr/hwpf/ifcompiler/initSymbols.C | 1056 |
1 files changed, 1056 insertions, 0 deletions
diff --git a/src/usr/hwpf/ifcompiler/initSymbols.C b/src/usr/hwpf/ifcompiler/initSymbols.C new file mode 100755 index 000000000..6e8b8bc38 --- /dev/null +++ b/src/usr/hwpf/ifcompiler/initSymbols.C @@ -0,0 +1,1056 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/ifcompiler/initSymbols.C,v $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 2010,2010 +// +//UNDEFINED +// +// Origin: UNDEFINED +// +// IBM_PROLOG_END_TAG +// Change Log ************************************************************************************* +// +// Flag Track Userid Date Description +// ---- -------- -------- -------- ------------------------------------------------------------- +// D754106 dgilbert 06/14/10 Create +// dgilbert 10/22/10 Add spies_are_in() +// andrewg 09/19/11 Updates based on review +// camvanng 11/08/11 Added support for attribute enums +// andrewg 11/09/11 Multi-dimensional array and move to common fapi include +// mjjones 11/17/11 Output attribute listing +// End Change Log ********************************************************************************* + +/** + * @file initSymbols.C + * @brief Definition of the initSymbols class. Handles all symbols for initfiles + */ + +#include <initSymbols.H> +#include <initRpn.H> +#include <sstream> +#include <iomanip> +#include <iostream> +#include <fstream> +#include <stdexcept> +#include <stdlib.h> + +using namespace init; + +ostringstream errss; + +#define SYM_EXPR 0x10000000 + +// ------------------------------------------------------------------------------------------------ + +Symbols::Symbols(FILELIST & i_filenames) + : iv_used_var_count(1), iv_used_lit_count(1), iv_rpn_id(1) +{ + string fileline; + + for(FILELIST::iterator fn = i_filenames.begin(); fn != i_filenames.end(); ++fn) + { + printf("Parsing file %s\n",fn->c_str()); + uint32_t lineno = 0; + ifstream infs(fn->c_str()); + if(!infs) + { + errss.str(""); + errss << "ERROR - Could not open " << *fn; + throw invalid_argument(errss.str()); + } + while(getline(infs,fileline)) + { + ++lineno; + if(fileline.size() == 0) continue; + if(fileline[0] == '/') continue; + istringstream iss(fileline); + string def; + iss >> def; + //printf("def: %s\n",def.c_str()); + if(def == "enum") + { + // Make sure it's the AttributeId enum + iss >> def; + if(def == "AttributeId") + { + // We've now found the beginning of the attribute enum definition + // Read and skip the '{' on the next line + getline(infs,fileline); + getline(infs,fileline); + + // We're just parsing the enum in order so values start + // at 0 and increment by 1 after that. + uint32_t value = 0; + + while(fileline[0] != '}') + { + istringstream attr_stream(fileline); + string attr; + attr_stream >> attr; + + // Strip off the "," at the end. + size_t pos = attr.find(','); + if(pos != string::npos) + { + attr = attr.substr(0,attr.length()-1); + } + + //printf("Attribute String:%s\n",attr.c_str()); + // We now have the first attribute loaded into attr + // Get a value for the string + + iv_symbols[attr] = MAP_DATA(value,NOT_USED); + value++; + getline(infs,fileline); + } + } + else + { + // Make sure it's an attribute enum + + string attribute_enum_name; + string find_enum = "_Enum"; + + // Check for _Enum in the name + size_t pos = def.find(find_enum); + if(pos != string::npos) + { + // We've now found the beginning of the attribute enum definition + // Read and skip the '{' on the next line + getline(infs,fileline); + getline(infs,fileline); + + // We're just parsing the enum in order so values start + // at 0 and increment by 1 after that unless they are + // explicitly assigned. + uint64_t value = 0; + + while(fileline[0] != '}') + { + istringstream attr_enum_stream(fileline); + string attr_enum; + string tmp; + + // Get the attribute enum name + attr_enum_stream >> attr_enum; + + // Strip off the "," at the end. + pos = attr_enum.find(','); + if(pos != string::npos) + { + attr_enum = attr_enum.substr(0,attr_enum.length()-1); + } + else + { + // Is a value for the enum specified? + attr_enum_stream >> tmp; + + if (!attr_enum_stream.eof()) + { + //Make sure it's an '=' + if ("=" != tmp) + { + printf ("ERROR: Unknown attribute enum! %s\n",attr_enum.c_str()); + exit(1); + } + else + { + attr_enum_stream >> tmp; + value = strtoll(tmp.c_str(), NULL, 0); + } + } + } + + //printf("Attribute Enum String:%s Value %u\n",attr_enum.c_str(), value); + + // Get a value for the string + iv_attr_enum[attr_enum] = value; + value++; + getline(infs,fileline); + } + } + } + } + else if(def == "typedef") + { + string type; + string attribute_name; + string find_type = "_Type"; + string find_array = "["; + uint32_t array = 0; + iss >> type; + iss >> attribute_name; + if(attribute_name == "*") + { + // It's a pointer type so read in the next string + iss >> attribute_name; + type = type + "*"; + } + //printf("typedef: type:%s attribute_name:%s\n",type.c_str(),attribute_name.c_str()); + + // Determine how many (if any) dimensions this array has + size_t pos = attribute_name.find(find_array); + while(pos != string::npos) + { + array++; + pos = attribute_name.find(find_array,pos+1); + } + + // Now strip off the _type in the name + pos = attribute_name.find(find_type); + if(pos != string::npos) + { + attribute_name = attribute_name.substr(0,pos); + } + else + { + printf ("ERROR: Unknown attribute type! %s\n",attribute_name.c_str()); + exit(1); + } + + iv_attr_type[attribute_name] = get_attr_type(type,array); + //printf("Attribute %s Type with array dimension %u for %s is %u\n",attribute_name.c_str(),array, + // type.c_str(),get_attr_type(type,array)); + } + } + infs.close(); + } + iv_rpn_map[Rpn::SYMBOL | INIT_EXPR_VAR] = RPN_DATA("EXPR",SYM_EXPR); + iv_rpn_map[Rpn::SYMBOL | INIT_ANY_LIT] = RPN_DATA("ANY",CINI_LIT_MASK); +} + +uint32_t Symbols::get_attr_type(const string &i_type, const uint32_t i_array) +{ + uint32_t l_type = 0; + + if (i_type == "uint8_t") + { + l_type = SYM_ATTR_UINT8_TYPE; + } + else if(i_type == "uint32_t") + { + l_type = SYM_ATTR_UINT32_TYPE; + } + else if(i_type == "uint64_t") + { + l_type = SYM_ATTR_UINT64_TYPE; + } + else + { + printf("Unknown data type: %s\n",i_type.c_str()); + exit(-1); + } + + if(i_array > MAX_ATTRIBUTE_ARRAY_DIMENSION) + { + printf("Array dimension size for %s %u exceeded maximum dimension of %u\n", + i_type.c_str(),i_array,MAX_ATTRIBUTE_ARRAY_DIMENSION); + exit(-1); + } + // See enum definition on why this works + l_type += (i_array*ATTR_DIMENSION_SIZE_MULT)+i_array; + + return(l_type); +} + +// ------------------------------------------------------------------------------------------------ + +void Symbols::add_define(const string * name, const Rpn * rpn) +{ + string s(*name); + translate_spyname(s); + iv_defines[s] = DEF_DATA(*rpn,NOT_USED); +} + +// ------------------------------------------------------------------------------------------------- + +Rpn Symbols::get_define_rpn(uint32_t rpn_id) +{ + Rpn r(this); + for(DEF_MAP::iterator i = iv_defines.begin(); i != iv_defines.end(); ++i) + { + if(i->second.second == rpn_id) + { + r = i->second.first; + break; + } + } + return r; +} + +// ------------------------------------------------------------------------------------------------ + +uint32_t Symbols::use_symbol(string & i_symbol) +{ + uint32_t rpn_id = Rpn::SYMBOL | NOT_FOUND; + if(i_symbol == "ANY") rpn_id = INIT_ANY_LIT | Rpn::SYMBOL; + else if(i_symbol == "EXPR") rpn_id = INIT_EXPR_VAR | Rpn::SYMBOL; + else if(i_symbol.compare(0,3,"DEF") == 0) + { + DEF_MAP::iterator i = iv_defines.find(i_symbol); + if(i != iv_defines.end()) + { + if(i->second.second == NOT_USED) + { + rpn_id = Rpn::DEFINE | iv_rpn_id++; + i->second.second = rpn_id; + } + else + { + rpn_id = i->second.second; + } + } + else + { + rpn_id = add_undefined(i_symbol); + } + } + else + { + SYMBOL_MAP::iterator i = iv_symbols.find(i_symbol); + if(i != iv_symbols.end()) + { + if(i->second.second == NOT_USED) + { + rpn_id = Rpn::SYMBOL | iv_rpn_id++; + i->second.second = rpn_id; + iv_rpn_map[rpn_id] = RPN_DATA(i_symbol,i->second.first); + + //printf ("Symbols::use_symbol: Just added %s symbol, rpn_id:0x%8X to iv_rpn_map\n",i_symbol.c_str(),rpn_id); + + if(i->second.first & CINI_LIT_MASK) ++iv_used_lit_count; + else ++iv_used_var_count; + } + else + { + rpn_id = i->second.second; + } + } + else + { + rpn_id = add_undefined(i_symbol); + } + } + + return rpn_id; +} + +// ------------------------------------------------------------------------------------------------ + +uint32_t Symbols::add_undefined(const string & i_symbol) +{ + uint32_t rpn_id = 0; + + SYMBOL_MAP::iterator i = iv_not_found.find(i_symbol); + if(i != iv_not_found.end()) + { + rpn_id = i->second.second; + } + else + { + rpn_id = Rpn::SYMBOL | iv_rpn_id++; + iv_not_found[i_symbol] = MAP_DATA(NOT_FOUND,rpn_id); + iv_rpn_map[rpn_id] = RPN_DATA(i_symbol,CINI_ID_NOT_FOUND); + } + return rpn_id; +} + +// ------------------------------------------------------------------------------------------------ + +uint16_t Symbols::get_tag(uint32_t i_rpn_id) +{ + uint16_t tag = NOT_FOUND; + uint32_t cini_id = CINI_ID_NOT_FOUND; + + // Set up tag table if not already setup + if(iv_used_var.size() == 0) + { + iv_used_var.reserve(iv_used_var_count); // makes if faster + iv_used_lit.reserve(iv_used_lit_count); + + iv_used_var.push_back(iv_rpn_map[Rpn::SYMBOL|INIT_EXPR_VAR].second); // EXPR var always first + iv_used_lit.push_back(iv_rpn_map[Rpn::SYMBOL|INIT_ANY_LIT].second); // ANY lit always first + + for(SYMBOL_MAP::iterator i = iv_symbols.begin(); i != iv_symbols.end(); ++i) + { + if(i->second.second != NOT_USED) + { + if((i->second.first & CINI_LIT_MASK) == CINI_LIT_MASK) + { + iv_used_lit.push_back(i->second.first); + } + else //VAR + { + iv_used_var.push_back(i->second.first); + } + } + } + } + + do + { + + RPN_MAP::iterator rm = iv_rpn_map.find(i_rpn_id); + if(rm != iv_rpn_map.end()) + { + cini_id = (rm->second).second; + } + else + { + //SYMBOL_MAP::iterator sm = iv_not_found.begin(); + //for(; sm != iv_not_found.end(); ++sm) + //{ + // if((sm->second).second == i_rpn_id) + // { + // break; + // } + //} + + //if(sm == iv_not_found.end()) + //{ + ostringstream err; + err << hex; + err << "ERROR! Symbols::get_tag() bad arg rpn_id = " << i_rpn_id << endl; + throw invalid_argument(err.str()); + //} + break; + } + + uint32_t offset = 0; + for(SYMBOL_USED::iterator i = iv_used_var.begin(); i != iv_used_var.end(); ++i,++offset) + { + if(cini_id == *i) + { + tag = (uint16_t) (offset | IF_ATTR_TYPE); + break; + } + } + + } while(0); + + return tag; +} + + + + +// ------------------------------------------------------------------------------------------------ + +string Symbols::find_name(uint32_t i_rpn_id) +{ + string name; + RPN_MAP::iterator rm = iv_rpn_map.find(i_rpn_id); + if(rm != iv_rpn_map.end()) + { + name = (rm->second).first; + } + else name = "NOT FOUND"; + return name; +} + +// ------------------------------------------------------------------------------------------------ + +uint32_t Symbols::find_numeric_lit(uint64_t i_data, int32_t byte_size) +{ + uint32_t offset = 0; + LIT_LIST::iterator i = iv_lits.begin(); + for(; i != iv_lits.end(); ++i,++offset) + { + if(i_data == i->first && (uint32_t)byte_size == i->second) + break; + } + if(i == iv_lits.end()) + { + iv_lits.push_back(LIT_DATA(i_data,byte_size)); + } + //printf("Symbols::find_numeric_lit: i_data:0x%llX byte_size:%d Tag:0x%X\n", + // i_data,byte_size, offset | Rpn::NUMBER); + return offset | Rpn::NUMBER; +} + +uint32_t Symbols::find_numeric_array_lit(uint64_t i_data, int32_t byte_size) +{ + uint32_t offset = 0; + LIT_LIST::iterator i = iv_lits.begin(); + for(; i != iv_lits.end(); ++i,++offset) + { + if(i_data == i->first && (uint32_t)byte_size == i->second) + break; + } + if(i == iv_lits.end()) + { + iv_lits.push_back(LIT_DATA(i_data,byte_size)); + } + //printf("Symbols::find_numeric_lit: i_data:0x%llX byte_size:%d Tag:0x%X\n", + // i_data,byte_size, offset | Rpn::NUMBER); + return offset | Rpn::ARRAY_INDEX; +} + +// ------------------------------------------------------------------------------------------------ + +uint16_t Symbols::get_numeric_tag(uint32_t i_rpn_id) +{ + uint32_t tag = NOT_FOUND; + uint32_t offset = i_rpn_id - Rpn::NUMBER; + string any("ANY"); + if(iv_used_lit.size() == 0) get_tag(use_symbol(any)); + if(offset < iv_lits.size()) + { + // numeric lits are numbered after enum lits, but with different TYPE + tag = (iv_used_lit.size() + offset) | IF_NUM_TYPE; + } + else + { + ostringstream err; + err << hex; + err << "ERROR! - Symbols::get_numeric_tag() invalid arg rpn_id = " << i_rpn_id << endl; + throw invalid_argument(err.str()); + } + return (uint16_t)tag; +} + +// ------------------------------------------------------------------------------------------------ + +uint16_t Symbols::get_numeric_array_tag(uint32_t i_rpn_id) +{ + uint32_t tag = NOT_FOUND; + uint32_t offset = i_rpn_id - Rpn::ARRAY_INDEX; + string any("ANY"); + if(iv_used_lit.size() == 0) get_tag(use_symbol(any)); + if(offset < iv_lits.size()) + { + // numeric lits are numbered after enum lits, but with different TYPE + tag = (iv_used_lit.size() + offset) | IF_NUM_TYPE; + } + else + { + ostringstream err; + err << hex; + err << "ERROR! - Symbols::get_numeric_array_tag() invalid arg rpn_id = " << i_rpn_id << endl; + throw invalid_argument(err.str()); + } + return (uint16_t)tag; +} + +// ------------------------------------------------------------------------------------------------ + +uint64_t Symbols::get_numeric_data(uint32_t i_rpn_id, uint32_t & o_size) +{ + uint64_t data = 0; + o_size = 0; + uint32_t offset = i_rpn_id - Rpn::NUMBER; + if(offset < iv_lits.size()) + { + LIT_DATA d = iv_lits[offset]; + data = d.first; + o_size = d.second; + } + else + { + ostringstream err; + err << hex; + err << "ERROR! - Symbols::get_numeric_data() invalid arg rpn_id = " << i_rpn_id << endl; + throw invalid_argument(err.str()); + } + return data; +} + +// ------------------------------------------------------------------------------------------------ +uint64_t Symbols::get_attr_enum_val(string & i_attr_enum) +{ + return iv_attr_enum[i_attr_enum]; +} + +// ------------------------------------------------------------------------------------------------ + +string Symbols::find_text(uint32_t i_cini_id) +{ + string name = "NOT FOUND"; + if(i_cini_id == CINI_LIT_MASK) name = "ANY"; + else if(i_cini_id == SYM_EXPR) name = "EXPR"; + else + { + for(SYMBOL_MAP::const_iterator i = iv_symbols.begin(); i != iv_symbols.end(); ++i) + { + //printf("SYMBOL:%s\n",i->first.c_str()); + if((i->second).first == i_cini_id) + { + name = i->first; + break; + } + } +// for(RPN_MAP::iterator i = iv_rpn_map.begin(); i != iv_rpn_map.end(); ++i) +// { +// if((i->second).second == i_cini_id) +// { +// name = (i->second).first; +// break; +// } +// } + } + return name; +} + + +// ------------------------------------------------------------------------------------------------ + +uint32_t Symbols::get_spy_id(const string & spyname) +{ + uint32_t id = NOT_FOUND; + string s = spyname; + translate_spyname(s); + SPY_MAP::iterator sm = iv_spymap.find(s); + if(sm != iv_spymap.end()) + { + id = sm->second; + } + else + { + size_t pos = s.find('-'); + if(pos == string::npos) s.insert(0,"SPY_"); + else + { + s[pos] = '_'; + s.insert(pos+1,"SPY_"); + s.insert(0,"ENUM_"); + } + iv_not_found[s] = MAP_DATA(0,0); + //cerr << "ERROR! Symbols::get_spy_id() Spyname not found " << '[' << s << ']' << endl; + } + return id; +} + +// ------------------------------------------------------------------------------------------------ + +uint32_t Symbols::use_enum(const string & enumname) +{ + uint32_t rpn_id = NOT_FOUND; + string s = enumname; + translate_spyname(s); + SPY_MAP::iterator sm = iv_enums.find(s); + if(sm != iv_enums.end()) + { + rpn_id = sm->second; + } + else + { + printf("Error!\n"); + exit(0); + } + return rpn_id; +} + +// ------------------------------------------------------------------------------------------------ + +uint32_t Symbols::get_spy_enum_id(uint32_t i_rpn_id, const string & spyname) +{ + //uint32_t id = NOT_FOUND; + string enumname = get_enum_name(i_rpn_id); + enumname.append("-"); + enumname.append(spyname); + return get_spy_id(enumname); +} + +// ------------------------------------------------------------------------------------------------ + +string Symbols::get_enum_name(uint32_t i_rpn_id) +{ + string name("SPY ENUM NOT FOUND"); + for(SPY_MAP::iterator i = iv_enums.begin(); i != iv_enums.end(); ++i) + { + if(i->second == i_rpn_id) + { + name = i->first; + break; + } + } + return name; +} + +// ------------------------------------------------------------------------------------------------ + +string Symbols::full_listing() +{ + uint32_t count = 0; + ostringstream oss; + oss << hex << setfill('0'); + + for(SYMBOL_MAP::iterator i = iv_symbols.begin(); i != iv_symbols.end(); ++i) + { + if(i->second.first < CINI_LIT_MASK) //VAR + { + ++count; + oss << "0x" << setw(8) << i->second.first << '\t' + << '[' << i->first << ']' << endl; + } + } + + ostringstream title; + title << "\n--------------- Attribute Symbol Table ---------------\n\n" + << "0x" << hex << setfill('0') << setw(8) << count << '\t' + << "Number of variables\n" << oss.str(); + + oss.str(""); + count = 0; + + for(SYMBOL_MAP::iterator i = iv_symbols.begin(); i != iv_symbols.end(); ++i) + { + if((i->second.first & CINI_LIT_MASK) == CINI_LIT_MASK) //LIT + { + ++count; + oss << "0x" << setw(8) << i->second.first << '\t' + << '[' << i->first << ']' << endl; + } + } + + title << "\n--------------- Literal Symbol Table -----------------\n\n" + << setw(8) << count << '\t' << "Number of enumerated literals\n" + << oss.str(); + + oss.str(""); + title << "\n-------------------- Spies and arrays ----------------------\n\n" + << "0x" << setw(8) << iv_spymap.size() << '\t' << "Number of spies and array symbols\n"; + + for(SPY_MAP::iterator i = iv_spymap.begin(); i != iv_spymap.end(); ++i) + { + oss << "0x" << setw(8) << i->second << '\t' << '[' << i->first << ']' << endl; + } + + title << oss.str(); + + return title.str(); +} + +// ------------------------------------------------------------------------------------------------ + +string Symbols::listing() +{ + uint32_t count = 0; + ostringstream oss; + + // Set up tag table if not already setup + string any = "ANY"; + get_tag(use_symbol(any)); + + oss << hex << setfill('0'); + + oss << "\n--------------- Attribute Symbol Table ---------------\n\n" + << "0x" << setw(4) << iv_used_var.size()-1 << '\t' << "Number of variables\n"; + + for(SYMBOL_USED::iterator i = iv_used_var.begin() + 1; i != iv_used_var.end(); ++i) + { + ++count; + oss << "Type:" << setw(2) << iv_attr_type[find_text(*i)] << " Value:0x" << setw(8) << (*i) << '\t' << "ID 0X" << setw(4) << (count | IF_ATTR_TYPE) + << '\t' << '[' << find_text(*i) << ']' << endl; + + //printf("ATTRIBUTE: %s Value:0x%02X\n",(find_text(*i)).c_str(),iv_attr_type[find_text(*i)]); + } + + count = 0; + + oss << "\n--------------- Literal Symbol Table -----------------\n\n"; + + oss << "\n0x" << setw(4) << iv_lits.size() << '\t' << "Number of numeric literals\n"; + + count = 0; + for(LIT_LIST::iterator i = iv_lits.begin(); i != iv_lits.end(); ++i,++count) + { + oss << "0x" << setw(2) << i->second << endl + << "0x" << setw(2 * i->second) << i->first; + if(i->second < 6) oss << "\t\t"; + else oss<< '\t'; + oss << "ID 0x" << setw(4) << get_numeric_tag(count | Rpn::NUMBER) << endl; + } + + oss << not_found_listing(); + + return oss.str(); +} + +// ------------------------------------------------------------------------------------------------ + +string Symbols::attr_listing() +{ + ostringstream oss; + + // Set up tag table if not already setup + string any = "ANY"; + get_tag(use_symbol(any)); + + for(SYMBOL_USED::iterator i = iv_used_var.begin() + 1; i != iv_used_var.end(); ++i) + { + oss << find_text(*i) << endl; + } + + return oss.str(); +} + +// ------------------------------------------------------------------------------------------------ + +string Symbols::not_found_listing() +{ + ostringstream oss; + if(iv_not_found.size()) + { + oss << "\n------------- Symbols requested that were NOT FOUND ---------------\n\n"; + for(SYMBOL_MAP::iterator i = iv_not_found.begin(); i != iv_not_found.end(); ++i) + { + //if(i->first == "SPY_NOTFOUND" || (i->first).compare(0,13,"ENUM_NOTFOUND") == 0) continue; + oss << '[' << i->first << ']' << endl; + } + } + return oss.str(); +} + +// ------------------------------------------------------------------------------------------------ + +uint32_t Symbols::bin_vars(BINSEQ & blist) +{ + // Set up tag table if not already setup + string any = "ANY"; + get_tag(use_symbol(any)); + + uint32_t count = iv_used_var.size() - 1; // first VAR is 'EXPR' and is not stored + + Rpn::set16(blist,(uint16_t)count); + + for(SYMBOL_USED::iterator i = iv_used_var.begin() + 1; i != iv_used_var.end(); ++i) + { + // Write out the attribute type (i.e. uint8_t, uint16_t, ...) and it's index number + Rpn::set8(blist,iv_attr_type[find_text(*i)]); + Rpn::set32(blist,(*i)); + //printf("Symbols::bin_vars: Just wrote out type:%u value:%u\n",iv_attr_type[find_text(*i)],*i); + } + return count; +} + +//------------------------------------------------------------------------------------------------- + +uint32_t Symbols::bin_lits(BINSEQ & blist) +{ + // Set up tag table if not already setup + string any = "ANY"; + get_tag(use_symbol(any)); + + uint32_t count = iv_lits.size(); + uint32_t total = count; + + Rpn::set16(blist,(uint16_t)count); + + for(LIT_LIST::iterator i = iv_lits.begin(); i != iv_lits.end(); ++i) + { + uint32_t size = i->second; + uint64_t data = i->first; + blist.push_back( (uint8_t)size ); + uint32_t shift_count = size * 8; + while(shift_count) + { + shift_count -= 8; + blist.push_back( (uint8_t)(data >> shift_count) ); + } + } + total += count; + + return total; +} + +//------------------------------------------------------------------------------------------------- + +uint32_t Symbols::restore_var_bseq(BINSEQ::const_iterator & bli) +{ + uint32_t count = Rpn::extract16(bli); + + iv_used_var.clear(); + iv_used_var.push_back(iv_rpn_map[Rpn::SYMBOL|INIT_EXPR_VAR].second); // EXPR var always first + + for(uint32_t i = 0; i < count; ++i) + { + uint8_t type = Rpn::extract8(bli); + uint32_t attribute = Rpn::extract32(bli); + iv_attr_type[find_text(attribute)] = type; + iv_used_var.push_back(attribute); + } + return count; +} + +//------------------------------------------------------------------------------------------------- + +uint32_t Symbols::restore_lit_bseq(BINSEQ::const_iterator & bli) +{ + iv_used_lit.clear(); + iv_used_lit.push_back(iv_rpn_map[Rpn::SYMBOL|INIT_ANY_LIT].second); // ANY lit always first + + iv_lits.clear(); + uint32_t num_count = Rpn::extract16(bli); + + for(uint32_t i = 0; i < num_count; ++i) + { + uint8_t size = *bli++; + uint64_t data = 0; + switch (size) + { + case 1: data = *bli++; break; + case 2: data = Rpn::extract16(bli); break; + case 4: data = Rpn::extract32(bli); break; + case 8: data = Rpn::extract64(bli); break; + default: + { + ostringstream errs; + errs << "ERROR! Symbols::restore_var_bseq(). Invalid literal data size [" + << size << ']' << endl; + throw invalid_argument(errs.str()); + } + break; + } + + iv_lits.push_back( LIT_DATA(data, size) ); + } + + return num_count; +} + +//------------------------------------------------------------------------------------------------- + +string Symbols::get_spyname(uint32_t spy_id) +{ + string name; + + for(SPY_MAP::const_iterator i = iv_spymap.begin(); i != iv_spymap.end(); ++i) + { + if (i->second == spy_id) + { + name = i->first; + break; + } + } + if(name.length() == 0) + { + ostringstream oss; + oss << hex << setfill('0'); + oss << "[0x" << setw(8) << spy_id << ']'; + name = oss.str(); + } + return name; +} +//------------------------------------------------------------------------------------------------- + +string Symbols::get_enumname(uint32_t spy_id) +{ + string name = get_spyname(spy_id); + size_t pos = name.find('-'); + if(pos != string::npos) + { + name = name.substr(0,pos); + } + return name; +} + +//------------------------------------------------------------------------------------------------- + +uint32_t Symbols::get_rpn_id(uint32_t bin_tag) +{ + uint32_t rpn_id = NOT_FOUND; + uint32_t type = bin_tag & IF_TYPE_MASK; + uint32_t offset = bin_tag & ~IF_TYPE_MASK; + uint32_t cini_id = 0; + switch(type) + { + case IF_ATTR_TYPE: { + cini_id = iv_used_var[offset]; + string name = find_text(cini_id); + rpn_id = use_symbol(name); + } + break; + + case IF_NUM_TYPE: { + offset -= iv_used_lit.size(); + if(offset >= iv_lits.size()) + { + ostringstream erros; + erros << hex; + erros << "ERROR! Symbols::get_rpn_id() Invalid NUM_TYPE 0x" + << bin_tag; + throw range_error(erros.str()); + } + LIT_DATA d = iv_lits[offset]; + rpn_id = find_numeric_lit(d.first,d.second); + } + break; + + default: + { + ostringstream erros; + erros << hex + << "ERROR! Symbols::get_rpn_id() Invalid bin_tag = 0x" + << bin_tag << endl; + throw range_error(erros.str()); + } + break; + } + return rpn_id; +} +//------------------------------------------------------------------------------------------------- + +string Symbols::spies_are_in(Symbols & i_full_list, const set<string> & i_ignore_spies) +{ + ostringstream result; + result << hex; + + for(SPY_MAP::iterator i = iv_spymap.begin(); i != iv_spymap.end(); ++i) + { + // enums in the reduced file will soon no longer contain the spyname as part of the enum name <enum name>-<spy name> + // At that time we will just need to check the enum part of the name <enum name> in both the ignore file and the full list + // When initfile processing AND spyhunter both use only enum names for enum spies then we can simplify all this + string spyname = i->first; + size_t pos = spyname.find('-'); // check for enum - if so just use the spy part of the name + if(pos != string::npos) + { + spyname = spyname.substr(pos+1); + } + + if(i_ignore_spies.find(spyname) != i_ignore_spies.end()) //don't check this spy or any of it's enums + { + cout << "Will not check spy: " << i->first << endl; + continue; + } + + uint32_t hash = 0; + if(pos != string::npos) // old enum style name - check by hash - only check enumname + { + // just compare enum names based on hash + string enumname1 = (i->first).substr(0,pos); + string enumname2 = i_full_list.get_enumname(i->second); + if(enumname1 != enumname2) + { + result << "ERROR! Enum not found for spy " << i->first << '\n' + << " Enum: " << enumname1 << "!=" << enumname2 << endl; + } + } + else // check spyname by name or new-style enum by name + { + hash = i_full_list.get_spy_id(i->first); + if(hash != NOT_FOUND) + { + if(hash != i->second) + { + result << "ERROR! HASH not the same for spy " + << i->first << ' ' << hash << ' ' << i->second << endl; + } + // else cout << "Found " << i->first << ' ' << i->second << endl; + } + } + } + result << i_full_list.not_found_listing(); + + + return result.str(); +} + + + + + |