Beispiel #1
0
 bool signed_by( const address& a ) {
    if( !available_address_sigs ) {
       available_address_sigs = std::map<address,public_key_type>();
       provided_address_sigs = std::map<address,public_key_type>();
       for( auto& item : available_keys ) {
        (*available_address_sigs)[ address(pts_address(item, false, 56) ) ] = item;
        (*available_address_sigs)[ address(pts_address(item, true, 56) ) ] = item;
        (*available_address_sigs)[ address(pts_address(item, false, 0) ) ] = item;
        (*available_address_sigs)[ address(pts_address(item, true, 0) ) ] = item;
        (*available_address_sigs)[ address(item) ] = item;
       }
       for( auto& item : provided_signatures ) {
        (*provided_address_sigs)[ address(pts_address(item.first, false, 56) ) ] = item.first;
        (*provided_address_sigs)[ address(pts_address(item.first, true, 56) ) ] = item.first;
        (*provided_address_sigs)[ address(pts_address(item.first, false, 0) ) ] = item.first;
        (*provided_address_sigs)[ address(pts_address(item.first, true, 0) ) ] = item.first;
        (*provided_address_sigs)[ address(item.first) ] = item.first;
       }
    }
    auto itr = provided_address_sigs->find(a);
    if( itr == provided_address_sigs->end() )
    {
       auto aitr = available_address_sigs->find(a);
       if( aitr != available_address_sigs->end() ) {
          auto pk = available_keys.find(aitr->second);
          if( pk != available_keys.end() )
             return provided_signatures[aitr->second] = true;
          return false;
       }
    }
    return provided_signatures[itr->second] = true;
 }
/** \brief Given a parsing table a \c pt and transition \c new_trans, if \c new_trans is a
    transition in \c pt, then return the successor table */
static optional<parse_table> find_match(optional<parse_table> const & pt, transition const & new_trans) {
    if (pt) {
        if (auto ls = pt->find(new_trans.get_token())) {
            for (auto at : ls) {
                if (new_trans.get_action().is_equal(at.first.get_action()))
                    return optional<parse_table>(at.second);
            }
        }
    }
    return optional<parse_table>();
}
/**
   \brief If the action for token \c tk in parse table \c pt is an Expr action,
   then return its precedence. We use this value as the default precedence
   when the user does not provide it. The idea is to minimize conflict with existing
   notation.
*/
static unsigned get_default_prec(optional<parse_table> const & pt, name const & tk) {
    if (!pt)
        return LEAN_DEFAULT_PRECEDENCE;
    if (auto ls = pt->find(tk)) {
        for (auto at : ls) {
            if (at.first.get_action().kind() == notation::action_kind::Expr)
                return at.first.get_action().rbp();
        }
    }
    return LEAN_DEFAULT_PRECEDENCE;
}
Beispiel #4
0
void print_type_die(std::ostream &_s, iterator_df<dwarf::core::basic_die> die_iter, optional<type_set&> types) {
	if (!die_iter) return;
	
	// Special case root early: just print all children
	if (die_iter.tag_here() == 0) {
		auto children = die_iter.children_here();
		for (auto iter = children.first; iter != children.second; iter++) {
			 print_type_die(_s, iter.base(), types);
			_s << endl;
		}
		return;
	}
	
	srk31::indenting_newline_ostream s(_s);
	//	auto &die = *die_iter;
	auto name_ptr = die_iter.name_here();
	auto tag = string(DEFAULT_DWARF_SPEC.tag_lookup(die_iter.tag_here())); 
	if (tag.compare("(unknown tag)") == 0) {
		// Leave unknown tags as hex
		tag = to_hex(die_iter.tag_here());
	} else {
		tag = tag.substr(7, string::npos); // remove DW_TAG_
	}
	auto offset = die_iter.offset_here();

	/* Offset, tag, name, type */

	bool offset_printed = false;
	bool name_printed = false;
	bool type_printed = false;
	
	if (offset) {
		s << "@0x" << std::hex << offset << std::dec << " ";
		offset_printed = true;
	}
	
	s << tag;

	if (name_ptr) {
		s << " " << *name_ptr;
		name_printed = true;
	}
	
	auto attrs = die_iter.copy_attrs(die_iter.get_root());
	auto &root = die_iter.get_root();

	/* Convert the type offset into a name if possible. */
	/* Two types (ha) of die with type information:
	   with_type_describing_layout_die => variables, members, etc, things *with* a type
	   type_describing_subprogram_die => subprograms (functions etc) *returning* a thing with a type
	   type_chain_die => things which are types with a type, e.g. typedefs, pointers, arrays
	   (yes, you're right, I can't count)
	*/
	dwarf::core::iterator_df<dwarf::core::type_die> type_die;
	auto with_type_iter = die_iter.as_a<with_type_describing_layout_die>();
	auto returning_type_iter = die_iter.as_a<type_describing_subprogram_die>();
	auto type_chain_iter = die_iter.as_a<type_chain_die>();
	if (with_type_iter) type_die = with_type_iter->get_type();
	else if (returning_type_iter) type_die = returning_type_iter->get_type();
	else if (type_chain_iter) type_die = type_chain_iter->get_type();
	
	if (type_die) {
		 // Dedup
		 if (types) {
			  auto dedup_type_iter = types->find(type_die);
			  //assert(dedup_type_iter != types->end());
			  if (dedup_type_iter != types->end()) {
				   _debug_print_dedup(type_die, *dedup_type_iter);
				   type_die = *dedup_type_iter;
			  }
		 }
		 auto abstract_name = type_die.name_here();
		 // Concretify (traverse typedefs etc)
		 auto concrete_die = type_die->get_concrete_type(root);
		 // Also dedup that. Just in case.
		 if (concrete_die && types) {
			  auto concrete_die_iter = types->find(concrete_die);
			  //assert(concrete_die_iter != types->end());
			  if (concrete_die_iter != types->end()) {
				   _debug_print_dedup(concrete_die, *concrete_die_iter);
				   concrete_die = *concrete_die_iter;
			  }
		 }
		 auto concrete_name = concrete_die.name_here();
		 auto type_name = (concrete_name ? concrete_name : abstract_name);
		 if (type_name) {
			  _debug_print_print(name_ptr, offset, type_die, concrete_die);
			  s << " : " << *type_name;
		 } else {
			  auto type_offset = (concrete_die ? concrete_die.offset_here() : type_die.offset_here());
			  s << " : @" << to_hex(type_offset);
			  
			  if (types->find(type_die) == types->end() && types->find(concrete_die) == types->end()) {
				   cerr << endl << "WARNING: a type was called for that wasn't in types!" << endl << "abstract: ";
				   type_die.print_with_attrs(cerr, 0);
				   cerr << endl << "concrete: ";
				   concrete_die.print_with_attrs(cerr, 0);
				   cerr << endl << "context: ";
				   die_iter.print_with_attrs(cerr, 0);
				   cerr << endl << endl;
			  }
			  type_printed = true;
		 }
		 
	} else {
		 try {
			  auto &v = attrs.at(DW_AT_type);
			  auto ref = v.get_ref();
			  s << " : " << (ref.abs ? "@" : "+") << to_hex(ref.off);
			  type_printed = true;
		 } catch (std::out_of_range) {}
	}
	
	/* Attribute list */

	if (name_printed) attrs.erase(DW_AT_name);
	if (type_printed) attrs.erase(DW_AT_type);
	if (attrs.size() > 0) {
		s << " [";
		s.inc_level();
		unsigned int attrs_printed = 0;
		for (auto iter = attrs.begin(); iter != attrs.end(); iter++) {
			auto pair = *iter;
			auto k = string(DEFAULT_DWARF_SPEC.attr_lookup(pair.first));
			if (k.compare("(unknown attribute)") == 0) {
				// FIXME FIXME FIXME
				continue;
				/* Leave unknown attributes as hex */
				k = to_hex(pair.first);
			} else {
				k = k.substr(6, string::npos); // remove DW_AT_
			}

			const char *drop_attrs[] = {
				 "decl_file",
				 "decl_line",
				 "prototyped",
				 "external",
				 "sibling",
				 nullptr
			};

			for (unsigned int i = 0; drop_attrs[i] != nullptr; i++) {
				 if (k.compare(drop_attrs[i]) == 0) {
					  continue;
				 }
			}
			
			auto v = pair.second;
			if (attrs_printed++ != 0) {
				s << "," << endl;
			}
			s << k << " = ";

			switch (v.get_form()) {
			case attribute_value::STRING: {
				string content = v.get_string();
				replace_all(content, "\\", "\\\\");
				replace_all(content, "\n", "\\n");
				replace_all(content, "\"", "\\\"");
				s << "\"" << content << "\"";
			}
				break;
			case attribute_value::FLAG: {
				if (v.get_flag()) {
					s << "true";
				} else {
					s << "false";
				}
			}
				break;
			case attribute_value::UNSIGNED:
				s << to_dec(v.get_unsigned()) << "u";
				break;
			case attribute_value::SIGNED:
				s << to_dec(v.get_signed());
				break;
			case attribute_value::ADDR:
				s << to_hex(v.get_address());
				break;
			case attribute_value::REF: {
				auto ref = v.get_ref();
				if (ref.abs) {
					s << "@";
				} else {
					s << "+";
				}
				s << to_hex(ref.off);
			}
				break;
			case attribute_value::LOCLIST: {
				auto loclist = v.get_loclist();
				if (loclist.size() == 1 && loclist[0].lopc == 0 && (loclist[0].hipc == 0 || loclist[0].hipc == std::numeric_limits<Dwarf_Addr>::max())) {
					s << "{";
					s.inc_level();
					auto locexpr = loclist[0];
					for (auto iter = locexpr.begin(); iter != locexpr.end(); iter++) {
						if (iter != locexpr.begin()) {
							s << endl;
						}
						s << opcode_to_string(*iter) << ";";
					}
					s.dec_level();
					s << "}";
					
				} else {
					s << "/* FIXME dummy location for multiple vaddr loclist */ { addr(0); }";
				}
			}
				break;
			default:
				s << "/* FIXME */ \"" << v << "\"";
				break;
			}
		}
		s.dec_level();
		s << "]";
	}

	/* Children list (recursively) */

	// auto lambda = [] (iterator_base &iter) {
	// 	return (iter.is_a<compile_unit_die>() || iter.is_a<member_die>() || iter.is_a<formal_parameter_die>() || iter.is_a<subprogram_die>() || iter.is_a<root_die>());
	// };
	auto children = die_iter.children_here(); //.subseq_with<decltype(lambda)>(lambda);
	
	if (children.first != children.second) {
		s << " {";
		s.inc_level();
		for (auto iter = children.first; iter != children.second; iter++) {
			 // user tags
			 if (iter.tag_here() > 0x4000) continue;
			 
			switch (iter.tag_here()) {
				// Only print these tags
			case DW_TAG_compile_unit:
			case DW_TAG_member:
			case DW_TAG_formal_parameter:
			case DW_TAG_subprogram:
			case 0: // root
				 print_type_die(s, iter.base(), types);
				s << endl;
				break;
			case DW_TAG_inlined_subroutine:
			case DW_TAG_lexical_block:
			case DW_TAG_variable:
				 // Specifically skip some.
				 continue; // definitely
				 break; // not confusing
			default:
				 print_type_die(s, iter.base(), types);
				 s << endl;
				 break;
			}
		}
		s.dec_level();
		s << "}";
	}
	
	s << ";";
}
/** \brief Lift parse_table::find method to optional<parse_table> */
static list<pair<transition, parse_table>> find_next(optional<parse_table> const & pt, name const & tk) {
    if (pt)
        return pt->find(tk);
    else
        return list<pair<transition, parse_table>>();
}