// Get pointer to func_t by routine name
func_t * get_func_by_name(const char *func_name)
{
	func_t * result_func = NULL;
	size_t func_total = get_func_qty();
	if (func_total > 0)
	{
		char tmp[1024];
		for (unsigned int i = 0; i < func_total - 1; i++)
		{
			func_t * func = getn_func(i);
			if (func != NULL)
			{
				memset(tmp, 0x00, sizeof(tmp));
				char *func_n = get_func_name(func->startEA, tmp, sizeof(tmp));
				if (func_n != NULL)
				{
					if (!strcmp(func_name, func_n))
					{
						result_func = func;
						break;
					}
				}
			}
		}
	}
	return result_func;
}
Exemplo n.º 2
0
void idaapi function_list::get_line(void *obj,uint32 n,char * const *arrptr)
{
  if ( n == 0 ) // generate the column headers
  {
    for ( int i=0; i < qnumber(header); i++ )
      qstrncpy(arrptr[i], header[i], MAXSTR);
    return;
  }
  function_list & ms = *(function_list*)obj;

  ea_t ea = ms.functions[n-1];
  qsnprintf(arrptr[0], MAXSTR, "%08a", ea);
  get_func_name(ea, arrptr[1], MAXSTR);
  //get_short_name(BADADDR, ea, arrptr[1], MAXSTR);
  //get_demangled_name(BADADDR, ea,  arrptr[1], MAXSTR, inf.long_demnames, DEMNAM_NAME, 0);
  func_t * f = get_func(ea);
  if(f)
  {
	  const char * cmt = get_func_cmt(f, true);
	  if(cmt)
	  {
		  qstrncpy(arrptr[2], cmt, MAXSTR);		
	  }
	
  }

}
Exemplo n.º 3
0
// The plugin can be passed an integer argument from the plugins.cfg
// file. This can be useful when you want the one plug-in to do
// something different depending on the hot-key pressed or menu
// item selected.
void IDAP_run(int arg)
{
	msg("%s run()\n", IDAP_name);

	// Disassemble the instruction at the cursor position, store it in
	// the global accessible "cmd" structure.
	// ua_out(get_screen_ea(), false);
	decode_insn( get_screen_ea() );

	// Display information about the first operand
	msg("itype = %u size = %zu\n", cmd.itype, cmd.size );
	for( unsigned int n = 0; n < UA_MAXOP ; ++n )
	{
		if( cmd.Operands[n].type == o_void ) break;
		msg("Operand %u n = %d type = %d reg = %d value = %a addr = %a\n",
			n,
			cmd.Operands[n].n,
			cmd.Operands[n].type,
			cmd.Operands[n].reg,
			cmd.Operands[n].value,
			cmd.Operands[n].addr);
	}

	char calleeName[MAXSTR];
	get_func_name(cmd.Op1.addr, calleeName, sizeof(calleeName));
	msg("Callee Name: \"%s\"", calleeName);

	return;
}
Exemplo n.º 4
0
Arquivo: proc.c Projeto: strk/postgres
/*
 * sepgsql_proc_relabel
 *
 * It checks privileges to relabel the supplied function
 * by the `seclabel'.
 */
void
sepgsql_proc_relabel(Oid functionId, const char *seclabel)
{
	char	   *scontext = sepgsql_get_client_label();
	char	   *tcontext;
	char	   *audit_name;

	audit_name = get_func_name(functionId);

	/*
	 * check db_procedure:{setattr relabelfrom} permission
	 */
	tcontext = sepgsql_get_label(ProcedureRelationId, functionId, 0);
	sepgsql_check_perms(scontext,
						tcontext,
						SEPG_CLASS_DB_PROCEDURE,
						SEPG_DB_PROCEDURE__SETATTR |
						SEPG_DB_PROCEDURE__RELABELFROM,
						audit_name,
						true);
	pfree(tcontext);

	/*
	 * check db_procedure:{relabelto} permission
	 */
	sepgsql_check_perms(scontext,
						seclabel,
						SEPG_CLASS_DB_PROCEDURE,
						SEPG_DB_PROCEDURE__RELABELTO,
						audit_name,
						true);
	pfree(audit_name);
}
Exemplo n.º 5
0
char *wrapped_get_func_name(ea_t ea)
{
	size_t bufsize = 0;
	char *function_name = get_func_name(ea, function_name_buffer, sizeof(function_name_buffer)-1);
	if (NULL == function_name) { return ""; }
	return function_name_buffer;
}
Exemplo n.º 6
0
//--------------------------------------------------------------------------
bool graph_info_t::get_title(ea_t func_ea, qstring *out)
{
  // we should succeed in getting the name
  char func_name[MAXSTR];
  if ( get_func_name(func_ea, func_name, sizeof(func_name)) == NULL )
    return false;
  out->sprnt("Call graph of: %s", func_name);
  return true;
}
//--------------------------------------------------------------------------
bool graph_info_t::get_title(ea_t func_ea, size_t num_inst, qstring *out)
{
  // we should succeed in getting the name
  char func_name[MAXSTR];
  if ( get_func_name(func_ea, func_name, sizeof(func_name)) == NULL )
    return false;

  out->sprnt("Ctree Graph View: %s %d", func_name, num_inst);
  
  return true;
}
Exemplo n.º 8
0
//----------------------------------------------------------------------
static void idaapi func_header(func_t *f) 
{
	char buf[256];
	char name[64];

   printf_line(0, "# =============== S U B R O U T I N E =======================================");
   printf_line(0, "");

	get_func_name(f->startEA, name, sizeof(name));
	init_output_buffer(buf, sizeof(buf));
	out_snprintf("def %s(", name);
	out_snprintf("...):");
	term_output_buffer();
	printf_line(0, "%s", buf);
	printf_line(0, "");

}
Exemplo n.º 9
0
void FindInvalidFunctionStartAndConnectBrokenFunctionChunk()
{
	int connected_links_count=0;
	do
	{
		connected_links_count=0;
		for(int i=0;i<get_func_qty();i++)
		{
			func_t *f=getn_func(i);
			char function_name[100]={0,};
			get_func_name(f->startEA,function_name,sizeof(function_name));
			if(!IsValidFunctionStart(f->startEA))
			{
				connected_links_count+=ConnectBrokenFunctionChunk(f->startEA);
			}		
		}
	}while(connected_links_count>0);
}
Exemplo n.º 10
0
//--------------------------------------------------------------------------
callgraph_t::funcinfo_t *callgraph_t::get_info(int nid)
{
  funcinfo_t *ret = NULL;

  do
  {
    // returned cached name
    int_funcinfo_map_t::iterator it = cached_funcs.find(nid);
    if ( it != cached_funcs.end() )
    {
      ret = &it->second;
      break;
    }

    // node does not exist?
    int_ea_map_t::const_iterator it_ea = node2ea.find(nid);
    if ( it_ea == node2ea.end() )
      break;

    func_t *pfn = get_func(it_ea->second);
    if ( pfn == NULL )
      break;

    funcinfo_t fi;

    // get name
    char buf[MAXSTR];
    if ( get_func_name(it_ea->second, buf, sizeof(buf)) == NULL )
      fi.name = "?";
    else
      fi.name = buf;

    // get color
    fi.color = calc_bg_color(pfn->startEA);

    fi.ea = pfn->startEA;

    it = cached_funcs.insert(cached_funcs.end(), std::make_pair(nid, fi));
    ret = &it->second;
  } while ( false );

  return ret;
}
Exemplo n.º 11
0
void stacktrace2(unsigned int max_frames, struct FILE_T *f, unsigned int *ebp)
{
    fprintf(f, "stack trace:\n");
    for(unsigned int frame = 0; frame < max_frames; ++frame)
    {
        unsigned int eip = ebp[1];
        if(eip == 0)
            break;

        ebp = (unsigned int *) ebp[0];
        //unsigned int *arguments = &ebp[2];
        char *name = get_func_name(eip);
        if (name) {
            fprintf(f, "  %p: %.32s\n", eip, name);
        } else {
            fprintf(f, "  %p: %.32s\n", eip, "unknown func");
            return;
        }
    }
}
Exemplo n.º 12
0
//Dump LIR stmts stored in fu->lirList array.
void dump_all_lir(LIRCode * fu, DexFile * df, DexMethod const* dm)
{
	if (g_tfile == NULL) return;
	IS_TRUE0(fu && df && dm);
	CHAR const* class_name = get_class_name(df, dm);
	CHAR const* func_name = get_func_name(df, dm);
	IS_TRUE0(class_name && func_name);
	fprintf(g_tfile, "\n==---- DUMP LIR of %s::%s ----== maxreg:%d ",
			class_name, func_name, fu->maxVars - 1);
	if (fu->maxVars > 0) {
		fprintf(g_tfile, "(");
		for (INT i = fu->maxVars - fu->numArgs; i < (INT)fu->maxVars; i++) {
			IS_TRUE0(i >= 0);
			fprintf(g_tfile, "v%d,", i);
		}
		fprintf(g_tfile, ")");
	}
	fprintf(g_tfile, " ====");
	if (fu->triesSize != 0) {
		for (UINT i = 0; i < fu->triesSize; i++) {
			fprintf(g_tfile, "\ntry%d, ", i);
			LIROpcodeTry * each_try = fu->trys + i;
			fprintf(g_tfile, "start_idx=%dth, end_idx=%dth",
					each_try->start_pc, each_try->end_pc);
			for (UINT j = 0; j < each_try->catchSize; j++) {
				LIROpcodeCatch * each_catch = each_try->catches + j;
				fprintf(g_tfile, "\n    catch%d, kind=%d, start_idx=%dth", j,
						each_catch->class_type,
						each_catch->handler_pc);
			}
		}
	}
	for (INT i = 0; i < LIRC_num_of_op(fu); i++) {
		LIR * lir = LIRC_op(fu, i);
		IS_TRUE0(lir);
		fprintf(g_tfile, "\n");
		dump_lir2(lir, df, i);
	}
	fflush(g_tfile);
}
Exemplo n.º 13
0
Arquivo: ui.c Projeto: wzcjj/wzcjj
static int cmd_bt(char *args) {
	swaddr_t addr = cpu.eip;
	uint32_t ebp = cpu.ebp;
	char fun_name[32];
	int i, flag, cnt = 0;
	while(ebp) {
		flag = 0;
		get_func_name(fun_name, addr, &flag);
		if(!flag) {
			printf("the program haven't start yet.\n");
			return 0;
		}
		printf("#%d\t0x%x\tin %s()\n", cnt++, addr, fun_name);
		if(strcmp(fun_name, "main") != 0) addr = swaddr_read(ebp + 4, 4, SR_SS);
		for(i = 0; i < 4; i ++) {
			printf("\t0x%08x", swaddr_read(ebp + ((i + 2) << 2), 4, SR_SS));
		}
		printf("\n");
		ebp = swaddr_read(ebp, 4, SR_SS);
	}
	return 0;
}
Exemplo n.º 14
0
Arquivo: init.c Projeto: rocsan/g-bios
static int __INIT__ system_init(void)
{
    int count;
    init_func_t *init_call;
    extern init_func_t init_call_begin[], init_call_end[];

    count = 1;
    init_call = init_call_begin;

    while (init_call < init_call_end) {
        int ret;
        const char *func_name;

        printf("%d. [0x%08x]", count, *init_call);
        func_name = get_func_name(*init_call);
        if (func_name)
            printf(" %s()", func_name);
        putchar('\n');

        ret = (*init_call)();
        if (ret < 0)
            puts("Failed!");
        else
            puts("OK!");

        init_call++;
        count++;

        printf("\n");
    }

    printf("(g-bios initialization finished.)\n");

    // show system information
    printf("%s\n", banner);

    return 0;
}
Exemplo n.º 15
0
char * pget_func_name(ea_t ea, char * buffer, size_t blen)
{
	char * pos;
	char tmp[512];

	if (!get_func_name(ea, buffer, blen))
		return NULL;

	// make sure this is not a c++ class/struct badly defined as a function
	demangle_name(tmp, blen, buffer, inf.long_demnames);
	if ( (strstr(tmp, "public: static") || strstr(tmp, "private: static")) &&
		(!strstr(tmp, "(") || strstr(tmp, "public: static long (__stdcall")) )
		 return NULL;

	demangle_name(buffer, blen, buffer, inf.short_demnames);

	// remove duplicates of the same name
	pos = strstr(buffer, "Z$0");
	if (pos)
		pos[0] = '\0';

	return buffer;
}
Exemplo n.º 16
0
char * ctree_dumper_t::parse_ctree_item(citem_t *item, char *buf, int bufsize) const
{
		char *ptr = buf;
		char *endp = buf + bufsize;
		
		// Each node will have the element type at the first line
		APPEND(ptr, endp, get_ctype_name(item->op));
		const cexpr_t *e = (const cexpr_t *)item;
		const cinsn_t *i = (const cinsn_t *)item;

		// For some item types, display additional information
		switch (item->op)
		{
		case cot_call:
			char buf[MAXSTR];
			if (e->x->op == cot_obj) {
				if (get_func_name(e->x->obj_ea, buf, sizeof(buf)) == NULL)
					ptr += qsnprintf(ptr, endp - ptr, " sub_%a", e->x->obj_ea);
				else 
					ptr += qsnprintf(ptr, endp - ptr, " %s", buf);
			}
			break;
		case cot_ptr: // *x
		case cot_memptr: // x->m
			// Display access size for pointers
			ptr += qsnprintf(ptr, endp - ptr, ".%d", e->ptrsize);
			if (item->op == cot_ptr)
				break;
		case cot_memref: // x.m
			// Display member offset for structure fields
			ptr += qsnprintf(ptr, endp - ptr, " (m=%d)", e->m);
			break;
		case cot_obj: // v
		case cot_var: // l
			// Display object size for local variables and global data
			ptr += qsnprintf(ptr, endp - ptr, ".%d", e->refwidth);
		case cot_num: // n
		case cot_helper: // arbitrary name
		case cot_str: // string constant
			// Display helper names and number values
			APPCHAR(ptr, endp, ' ');
			e->print1(ptr, endp - ptr, NULL);
			tag_remove(ptr, ptr, 0);
			ptr = tail(ptr);
			break;
		case cit_goto:
			// Display target label number for gotos
			ptr += qsnprintf(ptr, endp - ptr, " LABEL_%d", i->cgoto->label_num);
			break;
		case cit_asm:
			// Display instruction block address and size for asm-statements
			ptr += qsnprintf(ptr, endp - ptr, " %a.%" FMT_Z, *i->casm->begin(), i->casm->size());
			break;
		default:
			break;
		}
    
		// The second line of the node contains the item address
		ptr += qsnprintf(ptr, endp - ptr, ";ea->%a", item->ea);

		if ( item->is_expr() && !e->type.empty() )
		{
			// For typed expressions, the third line will have
			// the expression type in human readable form
			APPCHAR(ptr, endp, ';');
			qstring out;
			if (e->type.print(&out))
			{
				APPEND(ptr, endp, out.c_str());
			}
			else 
			{	// could not print the type?
				APPCHAR(ptr, endp, '?');
				APPZERO(ptr, endp);
			}

			if(e->type.is_ptr())
			{
				tinfo_t ptr_rem = ::remove_pointer(e->type);
				if(ptr_rem.is_struct())
				{
					qstring typenm;
					ptr_rem.print(&typenm, "prefix ", 0, 0, PRTYPE_MULTI | PRTYPE_TYPE | PRTYPE_SEMI);
				}
			}
		}
	
	return buf;
}
Exemplo n.º 17
0
/*
 * lookup_agg_function
 * common code for finding transfn, invtransfn, finalfn, and combinefn
 *
 * Returns OID of function, and stores its return type into *rettype
 *
 * NB: must not scribble on input_types[], as we may re-use those
 */
static Oid
lookup_agg_function(List *fnName,
					int nargs,
					Oid *input_types,
					Oid variadicArgType,
					Oid *rettype)
{
	Oid			fnOid;
	bool		retset;
	int			nvargs;
	Oid			vatype;
	Oid		   *true_oid_array;
	FuncDetailCode fdresult;
	AclResult	aclresult;
	int			i;

	/*
	 * func_get_detail looks up the function in the catalogs, does
	 * disambiguation for polymorphic functions, handles inheritance, and
	 * returns the funcid and type and set or singleton status of the
	 * function's return value.  it also returns the true argument types to
	 * the function.
	 */
	fdresult = func_get_detail(fnName, NIL, NIL,
							   nargs, input_types, false, false,
							   &fnOid, rettype, &retset,
							   &nvargs, &vatype,
							   &true_oid_array, NULL);

	/* only valid case is a normal function not returning a set */
	if (fdresult != FUNCDETAIL_NORMAL || !OidIsValid(fnOid))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_FUNCTION),
				 errmsg("function %s does not exist",
						func_signature_string(fnName, nargs,
											  NIL, input_types))));
	if (retset)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("function %s returns a set",
						func_signature_string(fnName, nargs,
											  NIL, input_types))));

	/*
	 * If the agg is declared to take VARIADIC ANY, the underlying functions
	 * had better be declared that way too, else they may receive too many
	 * parameters; but func_get_detail would have been happy with plain ANY.
	 * (Probably nothing very bad would happen, but it wouldn't work as the
	 * user expects.)  Other combinations should work without any special
	 * pushups, given that we told func_get_detail not to expand VARIADIC.
	 */
	if (variadicArgType == ANYOID && vatype != ANYOID)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("function %s must accept VARIADIC ANY to be used in this aggregate",
						func_signature_string(fnName, nargs,
											  NIL, input_types))));

	/*
	 * If there are any polymorphic types involved, enforce consistency, and
	 * possibly refine the result type.  It's OK if the result is still
	 * polymorphic at this point, though.
	 */
	*rettype = enforce_generic_type_consistency(input_types,
												true_oid_array,
												nargs,
												*rettype,
												true);

	/*
	 * func_get_detail will find functions requiring run-time argument type
	 * coercion, but nodeAgg.c isn't prepared to deal with that
	 */
	for (i = 0; i < nargs; i++)
	{
		if (!IsBinaryCoercible(input_types[i], true_oid_array[i]))
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("function %s requires run-time type coercion",
							func_signature_string(fnName, nargs,
												  NIL, true_oid_array))));
	}

	/* Check aggregate creator has permission to call the function */
	aclresult = pg_proc_aclcheck(fnOid, GetUserId(), ACL_EXECUTE);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(fnOid));

	return fnOid;
}
Exemplo n.º 18
0
//--------------------------------------------------------------------------
//
//      The plugin method
//
//      This is the main function of plugin.
//
void idaapi run(int /*arg*/)
{
  char title[MAXSTR];
  // Let's display the functions called from the current one
  // or from the selected area

  // First we determine the working area

  func_item_iterator_t fii;
  bool ok;
  ea_t ea1, ea2;
  if ( callui(ui_readsel, &ea1, &ea2).cnd )    // the selection is present?
  {
    callui(ui_unmarksel);                      // unmark selection
    qsnprintf(title, sizeof(title), "Functions called from %08a..%08a", ea1, ea2);
    ok = fii.set_range(ea1, ea2);
  }
  else                                         // nothing is selected
  {
    func_t *pfn = get_func(get_screen_ea());   // try the current function
    if ( pfn == NULL )
    {
      warning("Please position the cursor on a function or select an area");
      return;
    }
    ok = fii.set(pfn);
    static const char str[] = "Functions called from ";
    char *ptr = qstpncpy(title, str, sizeof(title));
    get_func_name(pfn->startEA, ptr, sizeof(title)-(ptr-title));
  }

  // We are going to remember the call instruction addresses
  // in a netnode
  // altval(i) will contain the address of the call instruction

  netnode *node = new netnode;
  node->create();
  int counter = 0;
  while ( ok )
  {
    ea_t ea = fii.current();
    if ( is_call_insn(ea) )       // a call instruction is found
      node->altset(counter++, ea);//get_first_fcref_from(ea));
    ok = fii.next_code();
  }

  // altval(-1) will contain the number of pairs
  node->altset(-1, counter);

  // now open the window
  choose2(0,                    // non-modal window
          -1, -1, -1, -1,       // position is determined by the OS
          node,                 // pass the created netnode to the window
          qnumber(header),      // number of columns
          widths,               // widths of columns
          sizer,                // function that returns number of lines
          desc,                 // function that generates a line
          title,                // window title
          -1,                   // use the default icon for the window
          0,                    // position the cursor on the first line
          NULL,                 // "kill" callback
          NULL,                 // "new" callback
          NULL,                 // "update" callback
          NULL,                 // "edit" callback
          enter_cb,             // function to call when the user pressed Enter
          destroy_cb,           // function to call when the window is closed
          NULL,                 // use default popup menu items
          NULL);                // use the same icon for all lines
}
Exemplo n.º 19
0
static void
dump_pdu(
	isns_pdu_t *pdu,
	int flag
)
{
	short ver, id, len, flags, xid, seq;

	uint8_t *payload = pdu->payload;
	isns_resp_t *resp;

	/* convert the data */
	if (flag) {
		ver = ntohs(pdu->version);
		id = ntohs(pdu->func_id);
		len = ntohs(pdu->payload_len);
		flags = ntohs(pdu->flags) & 0xFFFF;
		xid = ntohs(pdu->xid);
		seq = ntohs(pdu->seq);
	} else {
		ver = pdu->version;
		id = pdu->func_id;
		len = pdu->payload_len;
		flags = pdu->flags & 0xFFFF;
		xid = pdu->xid;
		seq = pdu->seq;
	}

	/* print the pdu header */
	printf("iSNSP Version: %d\n", ver);
	printf("Function ID: %s\n", get_func_name(id));
	printf("PDU Length: %d\n", len);
	printf("Flags: %x\n", flags);
	printf("    %d... .... .... .... : ISNS_FLAG_CLIENT\n",
	    ((flags & ISNS_FLAG_CLIENT) == 0) ? 0 : 1);
	printf("    .%d.. .... .... .... : ISNS_FLAG_SERVER\n",
	    ((flags & ISNS_FLAG_SERVER) == 0) ? 0 : 1);
	printf("    ..%d. .... .... .... : ISNS_FLAG_AUTH_BLK_PRESENTED\n",
	    ((flags & ISNS_FLAG_AUTH_BLK_PRESENTED) == 0) ? 0 : 1);
	printf("    ...%d .... .... .... : ISNS_FLAG_REPLACE_REG\n",
	    ((flags & ISNS_FLAG_REPLACE_REG) == 0) ? 0 : 1);
	printf("    .... %d... .... .... : ISNS_FLAG_LAST_PDU\n",
	    ((flags & ISNS_FLAG_LAST_PDU) == 0) ? 0 : 1);
	printf("    .... .%d.. .... .... : ISNS_FLAG_FIRST_PDU\n",
	    ((flags & ISNS_FLAG_FIRST_PDU) == 0) ? 0 : 1);
	printf("Transaction ID: %d\n", xid);
	printf("Sequence ID: %d\n", seq);

	printf("Payload: ...\n");
	if (id & ISNS_RSP_MASK) {
		resp = (isns_resp_t *)payload;
		printf("    ErrorCode: %d\n", ntohl(resp->status));
		len -= 4;
		payload += 4;
	}

	/* print the payload */
	while (len > 0) {
		isns_tlv_t *tlvp;
		int t, l;
		uint8_t *v;
		char *s;
		int i;
		in6_addr_t *ip;
		char pbuff[256] = { 0 };

		tlvp = (isns_tlv_t *)payload;

		/* convert the data */
		t = ntohl(tlvp->attr_id);
		l = ntohl(tlvp->attr_len);
		v = &(tlvp->attr_value[0]);

		/* print payload */
		if (l > 0) {
			printf("%s: ", get_tlv_tag_name(t));
			switch (t) {
				case ISNS_EID_ATTR_ID:
				case ISNS_ISCSI_NAME_ATTR_ID:
				case ISNS_ISCSI_ALIAS_ATTR_ID:
				case ISNS_ISCSI_AUTH_METHOD_ATTR_ID:
				case ISNS_PG_ISCSI_NAME_ATTR_ID:
				case ISNS_DD_NAME_ATTR_ID:
				case ISNS_DD_SET_NAME_ATTR_ID:
					s = (char *)v;
					printf("%s\n", s);
					break;
				case ISNS_ENTITY_PROTOCOL_ATTR_ID:
					i = ntohl(*(uint32_t *)v);
					printf("%s (%d)\n",
					    ((i == 1) ? "No Protocol" :
					    ((i == 2) ? "iSCSI" :
					    ((i == 3) ? "iFCP" :
					    "Others"))),
					    i);
					break;
				case ISNS_PORTAL_IP_ADDR_ATTR_ID:
				case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID:
					ip = (in6_addr_t *)v;
					inet_ntop(AF_INET6, (void *)ip,
					    pbuff, sizeof (pbuff));
					printf("%s\n", pbuff);
					break;
				case ISNS_PORTAL_PORT_ATTR_ID:
				case ISNS_ESI_PORT_ATTR_ID:
				case ISNS_SCN_PORT_ATTR_ID:
					i = ntohl(*(uint32_t *)v);
					printf("%d\n", (i & 0x0000FFFF));
					printf("    .... .... %d... .... : "
					    "0=TCP\n",
					    ((i & 0x10000) == 0) ? 0 : 1);
					break;
				case ISNS_ISCSI_NODE_TYPE_ATTR_ID:
					i = ntohl(*(uint32_t *)v);
					printf("0x%x\t", i);
					if (i & ISNS_CONTROL_NODE_TYPE) {
						printf("Control ");
					}
					if (i & ISNS_INITIATOR_NODE_TYPE) {
						printf("Initiator ");
					}
					if (i & ISNS_TARGET_NODE_TYPE) {
						printf("Target ");
					}
					printf("\n");
					break;
				case ISNS_PG_TAG_ATTR_ID:
				default:
					i = ntohl(*(uint32_t *)v);
					printf("%d\n", i);
					break;
			}
			printf("    Attribute Tag: %s (%d)\n",
			    get_tlv_tag_name(t), t);
			printf("    Attribute Length: %d\n", l);
		} else {
			printf("%s: (%d)\n", get_tlv_tag_name(t), t);
		}

		len -= (sizeof (uint32_t) * 2 + l);
		payload += (sizeof (uint32_t) * 2 + l);
	}
}
Exemplo n.º 20
0
TupleCheckStatus
FilterInit(Filter *filter, TupleDesc desc, Oid collation)
{
	int				i;
	ParsedFunction	func;
	HeapTuple		ftup;
	HeapTuple		ltup;
	Form_pg_proc	pp;
	Form_pg_language	lp;
	TupleCheckStatus	status = NEED_COERCION_CHECK;

	if (filter->funcstr == NULL)
		return NO_COERCION;

	/* parse filter function */
	func = ParseFunction(filter->funcstr, true);

	filter->funcid = func.oid;
	filter->nargs = func.nargs;
	for (i = 0; i < filter->nargs; i++)
	{
		/* Check for polymorphic types and internal pseudo-type argument */
		if (IsPolymorphicType(func.argtypes[i]) ||
			func.argtypes[i] == INTERNALOID)
			ereport(ERROR,
					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
					 errmsg("filter function does not support a polymorphic function and having a internal pseudo-type argument function: %s",
							get_func_name(filter->funcid))));

		filter->argtypes[i] = func.argtypes[i];
	}

	ftup = SearchSysCache(PROCOID, ObjectIdGetDatum(filter->funcid), 0, 0, 0);
	pp = (Form_pg_proc) GETSTRUCT(ftup);

	if (pp->proretset)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("filter function must not return set")));

	/* Check data type of the function result value */
	if (pp->prorettype == desc->tdtypeid && pp->prorettype != RECORDOID)
		status = NO_COERCION;
	else if (pp->prorettype == RECORDOID)
	{
		TupleDesc	resultDesc = NULL;

		/* Check for OUT parameters defining a RECORD result */
		resultDesc = build_function_result_tupdesc_t(ftup);

		if (resultDesc)
		{
			if (tupledesc_match(desc, resultDesc))
				status = NO_COERCION;

			FreeTupleDesc(resultDesc);
		}
	}
	else if (get_typtype(pp->prorettype) != TYPTYPE_COMPOSITE)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("function return data type and target table data type do not match")));

	/* Get default values */
#if PG_VERSION_NUM >= 80400
	filter->fn_ndargs = pp->pronargdefaults;
	if (filter->fn_ndargs > 0)
	{
		Datum		proargdefaults;
		bool		isnull;
		char	   *str;
		List	   *defaults;
		ListCell   *l;

		filter->defaultValues = palloc(sizeof(Datum) * filter->fn_ndargs);
		filter->defaultIsnull = palloc(sizeof(bool) * filter->fn_ndargs);

		proargdefaults = SysCacheGetAttr(PROCOID, ftup,
										 Anum_pg_proc_proargdefaults,
										 &isnull);
		Assert(!isnull);
		str = TextDatumGetCString(proargdefaults);
		defaults = (List *) stringToNode(str);
		Assert(IsA(defaults, List));
		pfree(str);

		filter->econtext = CreateStandaloneExprContext();
		i = 0;
		foreach(l, defaults)
		{
			Expr		   *expr = (Expr *) lfirst(l);
			ExprState	   *argstate;
			ExprDoneCond	thisArgIsDone;

			argstate = ExecInitExpr(expr, NULL);

			filter->defaultValues[i] = ExecEvalExpr(argstate,
													filter->econtext,
													&filter->defaultIsnull[i],
													&thisArgIsDone);

			if (thisArgIsDone != ExprSingleResult)
				ereport(ERROR,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("functions and operators can take at most one set argument")));

			i++;
		}
Exemplo n.º 21
0
/*
 * lookup_agg_function -- common code for finding both transfn and finalfn
 */
static Oid
lookup_agg_function(List *fnName,
					int nargs,
					Oid *input_types,
					Oid *rettype)
{
	Oid			fnOid;
	bool		retset;
	int			nvargs;
	Oid		   *true_oid_array;
	FuncDetailCode fdresult;
	AclResult	aclresult;
	int			i;

	/*
	 * func_get_detail looks up the function in the catalogs, does
	 * disambiguation for polymorphic functions, handles inheritance, and
	 * returns the funcid and type and set or singleton status of the
	 * function's return value.  it also returns the true argument types to
	 * the function.
	 */
	fdresult = func_get_detail(fnName, NIL, nargs, input_types, false, false,
							   &fnOid, rettype, &retset, &nvargs,
							   &true_oid_array, NULL);

	/* only valid case is a normal function not returning a set */
	if (fdresult != FUNCDETAIL_NORMAL || !OidIsValid(fnOid))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_FUNCTION),
				 errmsg("function %s does not exist",
						func_signature_string(fnName, nargs, input_types))));
	if (retset)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("function %s returns a set",
						func_signature_string(fnName, nargs, input_types))));

	/*
	 * If there are any polymorphic types involved, enforce consistency, and
	 * possibly refine the result type.  It's OK if the result is still
	 * polymorphic at this point, though.
	 */
	*rettype = enforce_generic_type_consistency(input_types,
												true_oid_array,
												nargs,
												*rettype,
												true);

	/*
	 * func_get_detail will find functions requiring run-time argument type
	 * coercion, but nodeAgg.c isn't prepared to deal with that
	 */
	for (i = 0; i < nargs; i++)
	{
		if (!IsPolymorphicType(true_oid_array[i]) &&
			!IsBinaryCoercible(input_types[i], true_oid_array[i]))
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("function %s requires run-time type coercion",
					 func_signature_string(fnName, nargs, true_oid_array))));
	}

	/* Check aggregate creator has permission to call the function */
	aclresult = pg_proc_aclcheck(fnOid, GetUserId(), ACL_EXECUTE);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(fnOid));

	return fnOid;
}
Exemplo n.º 22
0
/*
 * ValidateProtocolFunction -- common code for finding readfn, writefn or validatorfn
 */
static Oid
ValidateProtocolFunction(List *fnName, ExtPtcFuncType fntype)
{
	Oid			fnOid;
	bool		retset;
	bool        retstrict;
	bool        retordered;
	Oid		   *true_oid_array;
	Oid 	    actual_rettype;
	Oid			desired_rettype;
	FuncDetailCode fdresult;
	AclResult	aclresult;
	Oid 		inputTypes[1] = {InvalidOid}; /* dummy */
	int			nargs = 0; /* true for all 3 function types at the moment */
	int			nvargs;
	
	if (fntype == EXTPTC_FUNC_VALIDATOR)
		desired_rettype = VOIDOID;
	else
		desired_rettype = INT4OID;

	/*
	 * func_get_detail looks up the function in the catalogs, does
	 * disambiguation for polymorphic functions, handles inheritance, and
	 * returns the funcid and type and set or singleton status of the
	 * function's return value.  it also returns the true argument types to
	 * the function.
	 */
	fdresult = func_get_detail(fnName, NIL, nargs, inputTypes, false, false,
							   &fnOid, &actual_rettype, &retset, &retstrict,
							   &retordered, &nvargs, &true_oid_array, NULL);

	/* only valid case is a normal function not returning a set */
	if (fdresult != FUNCDETAIL_NORMAL || !OidIsValid(fnOid))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_FUNCTION),
				 errmsg("function %s does not exist",
						func_signature_string(fnName, nargs, inputTypes))));
	
	if (retset)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("Invalid protocol function"),
				 errdetail("Protocol functions cannot return sets.")));		

	if (actual_rettype != desired_rettype)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("%s protocol function %s must return %s",
						func_type_to_name(fntype),
						func_signature_string(fnName, nargs, inputTypes),
						(fntype == EXTPTC_FUNC_VALIDATOR ? "void" : "an integer"))));
	
	if (func_volatile(fnOid) == PROVOLATILE_IMMUTABLE)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
				 errmsg("%s protocol function %s is declared IMMUTABLE",
						func_type_to_name(fntype),
						func_signature_string(fnName, nargs, inputTypes)),
				 errhint("PROTOCOL functions must be declared STABLE or VOLATILE")));

	
	/* Check protocol creator has permission to call the function */
	aclresult = pg_proc_aclcheck(fnOid, GetUserId(), ACL_EXECUTE);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(fnOid));

	return fnOid;
}
Exemplo n.º 23
0
void __stdcall FuncName(__int64 addr, char *buf, size_t bufsize){ get_func_name((ea_t)addr, buf, bufsize);}
Exemplo n.º 24
0
bool idaapi extract_all_types(void *ud)
{
	logmsg(DEBUG, "extract_types()\n");

	// find vtables in the binary
	search_objects(false);

	qvector <VTBL_info_t>::iterator vtbl_iter;

	std::map<ea_t, VTBL_info_t> vtbl_map;
	for (vtbl_iter = vtbl_t_list.begin(); vtbl_iter != vtbl_t_list.end(); vtbl_iter++)
		vtbl_map[(*vtbl_iter).ea_begin] = (*vtbl_iter);

	int file_id = create_open_file("types.txt");
	if (file_id == -1)
	{
		logmsg(ERROR, "Failed to open file for dumping types.txt\r\n");
		return false;
	}

	int struct_no = 0;

	for (vtbl_iter = vtbl_t_list.begin(); vtbl_iter != vtbl_t_list.end(); vtbl_iter++) {
		qstring info_msg;
		info_msg.cat_sprnt("Processing vtable %s\n", (*vtbl_iter).vtbl_name.c_str());
		logmsg(DEBUG, info_msg.c_str());

		qstring type_name;
		type_name.sprnt("struc_2_%d", struct_no);

		ea_t cur_vt_ea = (*vtbl_iter).ea_begin;
		int struct_subno = 0;

		qvector <qstring> types_to_merge;
		for (ea_t addr = get_first_dref_to(cur_vt_ea); addr != BADADDR; addr = get_next_dref_to(cur_vt_ea, addr)) {
			qstring name;
			if (get_func_name(&name, addr) <= 0)
				continue;

			qstring info_msg1;
			info_msg1.cat_sprnt("\t%s\n", name.c_str());
			logmsg(DEBUG, info_msg1.c_str());

			func_t *pfn = get_func(addr);
			if (!pfn)
				continue;

			hexrays_failure_t hf;
			cfuncptr_t cfunc = decompile(pfn, &hf);
			if (cfunc != NULL) {
				qstring var_name;
				info_msg.clear();

				if (find_var(cfunc, (*vtbl_iter).vtbl_name, var_name)) {
					info_msg.cat_sprnt(" : %s\n", var_name.c_str());
					logmsg(DEBUG, info_msg.c_str());

					qstring sub_type_name = type_name;
					sub_type_name.cat_sprnt("_%d", struct_subno);
					struct_subno++;

					if (reconstruct_type(cfunc, var_name, sub_type_name)) {
						if (check_subtype((*vtbl_iter), sub_type_name)) {
							types_to_merge.push_back(sub_type_name);
						}
					}
				}
				else {
					info_msg.cat_sprnt(" : none\n");
					logmsg(DEBUG, info_msg.c_str());
				}
			}
		}

		struct_no++;

		merge_types(types_to_merge, type_name);
		dump_type_info(file_id, (*vtbl_iter), type_name, vtbl_map);
	}

	qclose(file_id);
	return true;
}
Exemplo n.º 25
0
/*
 * lookup_agg_function -- common code for finding both transfn and finalfn
 */
static Oid
lookup_agg_function(List *fnName,
					int nargs,
					Oid *input_types,
					Oid *rettype)
{
	Oid			fnOid;
	bool		retset;
	Oid		   *true_oid_array;
	FuncDetailCode fdresult;
	AclResult	aclresult;

	/*
	 * func_get_detail looks up the function in the catalogs, does
	 * disambiguation for polymorphic functions, handles inheritance, and
	 * returns the funcid and type and set or singleton status of the
	 * function's return value.  it also returns the true argument types
	 * to the function.
	 */
	fdresult = func_get_detail(fnName, NIL, nargs, input_types,
							   &fnOid, rettype, &retset,
							   &true_oid_array);

	/* only valid case is a normal function not returning a set */
	if (fdresult != FUNCDETAIL_NORMAL || !OidIsValid(fnOid))
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_FUNCTION),
				 errmsg("function %s does not exist",
					func_signature_string(fnName, nargs, input_types))));
	if (retset)
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("function %s returns a set",
					func_signature_string(fnName, nargs, input_types))));

	/*
	 * If the given type(s) are all polymorphic, there's nothing we can
	 * check.  Otherwise, enforce consistency, and possibly refine the
	 * result type.
	 */
	if ((input_types[0] == ANYARRAYOID || input_types[0] == ANYELEMENTOID) &&
		(nargs == 1 ||
	 (input_types[1] == ANYARRAYOID || input_types[1] == ANYELEMENTOID)))
	{
		/* nothing to check here */
	}
	else
	{
		*rettype = enforce_generic_type_consistency(input_types,
													true_oid_array,
													nargs,
													*rettype);
	}

	/*
	 * func_get_detail will find functions requiring run-time argument
	 * type coercion, but nodeAgg.c isn't prepared to deal with that
	 */
	if (true_oid_array[0] != ANYARRAYOID &&
		true_oid_array[0] != ANYELEMENTOID &&
		!IsBinaryCoercible(input_types[0], true_oid_array[0]))
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("function %s requires run-time type coercion",
				 func_signature_string(fnName, nargs, true_oid_array))));

	if (nargs == 2 &&
		true_oid_array[1] != ANYARRAYOID &&
		true_oid_array[1] != ANYELEMENTOID &&
		!IsBinaryCoercible(input_types[1], true_oid_array[1]))
		ereport(ERROR,
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("function %s requires run-time type coercion",
				 func_signature_string(fnName, nargs, true_oid_array))));

	/* Check aggregate creator has permission to call the function */
	aclresult = pg_proc_aclcheck(fnOid, GetUserId(), ACL_EXECUTE);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, ACL_KIND_PROC, get_func_name(fnOid));

	return fnOid;
}
Exemplo n.º 26
0
Expression::ENode *Expression::_parse_expression() {

	Vector<ExpressionNode> expression;

	while (true) {
		//keep appending stuff to expression
		ENode *expr = NULL;

		Token tk;
		_get_token(tk);
		if (error_set)
			return NULL;

		switch (tk.type) {
			case TK_CURLY_BRACKET_OPEN: {
				//a dictionary
				DictionaryNode *dn = alloc_node<DictionaryNode>();

				while (true) {

					int cofs = str_ofs;
					_get_token(tk);
					if (tk.type == TK_CURLY_BRACKET_CLOSE) {
						break;
					}
					str_ofs = cofs; //revert
					//parse an expression
					ENode *subexpr = _parse_expression();
					if (!subexpr)
						return NULL;
					dn->dict.push_back(subexpr);

					_get_token(tk);
					if (tk.type != TK_COLON) {
						_set_error("Expected ':'");
						return NULL;
					}

					subexpr = _parse_expression();
					if (!subexpr)
						return NULL;

					dn->dict.push_back(subexpr);

					cofs = str_ofs;
					_get_token(tk);
					if (tk.type == TK_COMMA) {
						//all good
					} else if (tk.type == TK_CURLY_BRACKET_CLOSE) {
						str_ofs = cofs;
					} else {
						_set_error("Expected ',' or '}'");
					}
				}

				expr = dn;
			} break;
			case TK_BRACKET_OPEN: {
				//an array

				ArrayNode *an = alloc_node<ArrayNode>();

				while (true) {

					int cofs = str_ofs;
					_get_token(tk);
					if (tk.type == TK_BRACKET_CLOSE) {
						break;
					}
					str_ofs = cofs; //revert
					//parse an expression
					ENode *subexpr = _parse_expression();
					if (!subexpr)
						return NULL;
					an->array.push_back(subexpr);

					cofs = str_ofs;
					_get_token(tk);
					if (tk.type == TK_COMMA) {
						//all good
					} else if (tk.type == TK_BRACKET_CLOSE) {
						str_ofs = cofs;
					} else {
						_set_error("Expected ',' or ']'");
					}
				}

				expr = an;
			} break;
			case TK_PARENTHESIS_OPEN: {
				//a suexpression
				ENode *e = _parse_expression();
				if (error_set)
					return NULL;
				_get_token(tk);
				if (tk.type != TK_PARENTHESIS_CLOSE) {
					_set_error("Expected ')'");
					return NULL;
				}

				expr = e;

			} break;
			case TK_IDENTIFIER: {

				String identifier = tk.value;

				int cofs = str_ofs;
				_get_token(tk);
				if (tk.type == TK_PARENTHESIS_OPEN) {
					//function call
					CallNode *func_call = alloc_node<CallNode>();
					func_call->method = identifier;
					SelfNode *self_node = alloc_node<SelfNode>();
					func_call->base = self_node;

					while (true) {

						int cofs2 = str_ofs;
						_get_token(tk);
						if (tk.type == TK_PARENTHESIS_CLOSE) {
							break;
						}
						str_ofs = cofs2; //revert
						//parse an expression
						ENode *subexpr = _parse_expression();
						if (!subexpr)
							return NULL;

						func_call->arguments.push_back(subexpr);

						cofs2 = str_ofs;
						_get_token(tk);
						if (tk.type == TK_COMMA) {
							//all good
						} else if (tk.type == TK_PARENTHESIS_CLOSE) {
							str_ofs = cofs2;
						} else {
							_set_error("Expected ',' or ')'");
						}
					}

					expr = func_call;
				} else {
					//named indexing
					str_ofs = cofs;

					int input_index = -1;
					for (int i = 0; i < input_names.size(); i++) {
						if (input_names[i] == identifier) {
							input_index = i;
							break;
						}
					}

					if (input_index != -1) {
						InputNode *input = alloc_node<InputNode>();
						input->index = input_index;
						expr = input;
					} else {

						NamedIndexNode *index = alloc_node<NamedIndexNode>();
						SelfNode *self_node = alloc_node<SelfNode>();
						index->base = self_node;
						index->name = identifier;
						expr = index;
					}
				}
			} break;
			case TK_INPUT: {

				InputNode *input = alloc_node<InputNode>();
				input->index = tk.value;
				expr = input;
			} break;
			case TK_SELF: {

				SelfNode *self = alloc_node<SelfNode>();
				expr = self;
			} break;
			case TK_CONSTANT: {
				ConstantNode *constant = alloc_node<ConstantNode>();
				constant->value = tk.value;
				expr = constant;
			} break;
			case TK_BASIC_TYPE: {
				//constructor..

				Variant::Type bt = Variant::Type(int(tk.value));
				_get_token(tk);
				if (tk.type != TK_PARENTHESIS_OPEN) {
					_set_error("Expected '('");
					return NULL;
				}

				ConstructorNode *constructor = alloc_node<ConstructorNode>();
				constructor->data_type = bt;

				while (true) {

					int cofs = str_ofs;
					_get_token(tk);
					if (tk.type == TK_PARENTHESIS_CLOSE) {
						break;
					}
					str_ofs = cofs; //revert
					//parse an expression
					ENode *subexpr = _parse_expression();
					if (!subexpr)
						return NULL;

					constructor->arguments.push_back(subexpr);

					cofs = str_ofs;
					_get_token(tk);
					if (tk.type == TK_COMMA) {
						//all good
					} else if (tk.type == TK_PARENTHESIS_CLOSE) {
						str_ofs = cofs;
					} else {
						_set_error("Expected ',' or ')'");
					}
				}

				expr = constructor;

			} break;
			case TK_BUILTIN_FUNC: {
				//builtin function

				_get_token(tk);
				if (tk.type != TK_PARENTHESIS_OPEN) {
					_set_error("Expected '('");
					return NULL;
				}

				BuiltinFuncNode *bifunc = alloc_node<BuiltinFuncNode>();
				bifunc->func = BuiltinFunc(int(tk.value));

				while (true) {

					int cofs = str_ofs;
					_get_token(tk);
					if (tk.type == TK_PARENTHESIS_CLOSE) {
						break;
					}
					str_ofs = cofs; //revert
					//parse an expression
					ENode *subexpr = _parse_expression();
					if (!subexpr)
						return NULL;

					bifunc->arguments.push_back(subexpr);

					cofs = str_ofs;
					_get_token(tk);
					if (tk.type == TK_COMMA) {
						//all good
					} else if (tk.type == TK_PARENTHESIS_CLOSE) {
						str_ofs = cofs;
					} else {
						_set_error("Expected ',' or ')'");
					}
				}

				int expected_args = get_func_argument_count(bifunc->func);
				if (bifunc->arguments.size() != expected_args) {
					_set_error("Builtin func '" + get_func_name(bifunc->func) + "' expects " + itos(expected_args) + " arguments.");
				}

				expr = bifunc;

			} break;
			case TK_OP_SUB: {

				ExpressionNode e;
				e.is_op = true;
				e.op = Variant::OP_NEGATE;
				expression.push_back(e);
				continue;
			} break;
			case TK_OP_NOT: {

				ExpressionNode e;
				e.is_op = true;
				e.op = Variant::OP_NOT;
				expression.push_back(e);
				continue;
			} break;

			default: {
				_set_error("Expected expression.");
				return NULL;
			} break;
		}

		//before going to operators, must check indexing!

		while (true) {
			int cofs2 = str_ofs;
			_get_token(tk);
			if (error_set)
				return NULL;

			bool done = false;

			switch (tk.type) {
				case TK_BRACKET_OPEN: {
					//value indexing

					IndexNode *index = alloc_node<IndexNode>();
					index->base = expr;

					ENode *what = _parse_expression();
					if (!what)
						return NULL;

					index->index = what;

					_get_token(tk);
					if (tk.type != TK_BRACKET_CLOSE) {
						_set_error("Expected ']' at end of index.");
						return NULL;
					}
					expr = index;

				} break;
				case TK_PERIOD: {
					//named indexing or function call
					_get_token(tk);
					if (tk.type != TK_IDENTIFIER) {
						_set_error("Expected identifier after '.'");
						return NULL;
					}

					StringName identifier = tk.value;

					int cofs = str_ofs;
					_get_token(tk);
					if (tk.type == TK_PARENTHESIS_OPEN) {
						//function call
						CallNode *func_call = alloc_node<CallNode>();
						func_call->method = identifier;
						func_call->base = expr;

						while (true) {

							int cofs3 = str_ofs;
							_get_token(tk);
							if (tk.type == TK_PARENTHESIS_CLOSE) {
								break;
							}
							str_ofs = cofs3; //revert
							//parse an expression
							ENode *subexpr = _parse_expression();
							if (!subexpr)
								return NULL;

							func_call->arguments.push_back(subexpr);

							cofs3 = str_ofs;
							_get_token(tk);
							if (tk.type == TK_COMMA) {
								//all good
							} else if (tk.type == TK_PARENTHESIS_CLOSE) {
								str_ofs = cofs3;
							} else {
								_set_error("Expected ',' or ')'");
							}
						}

						expr = func_call;
					} else {
						//named indexing
						str_ofs = cofs;

						NamedIndexNode *index = alloc_node<NamedIndexNode>();
						index->base = expr;
						index->name = identifier;
						expr = index;
					}

				} break;
				default: {
					str_ofs = cofs2;
					done = true;
				} break;
			}

			if (done)
				break;
		}

		//push expression
		{
			ExpressionNode e;
			e.is_op = false;
			e.node = expr;
			expression.push_back(e);
		}

		//ok finally look for an operator

		int cofs = str_ofs;
		_get_token(tk);
		if (error_set)
			return NULL;

		Variant::Operator op = Variant::OP_MAX;

		switch (tk.type) {
			case TK_OP_IN: op = Variant::OP_IN; break;
			case TK_OP_EQUAL: op = Variant::OP_EQUAL; break;
			case TK_OP_NOT_EQUAL: op = Variant::OP_NOT_EQUAL; break;
			case TK_OP_LESS: op = Variant::OP_LESS; break;
			case TK_OP_LESS_EQUAL: op = Variant::OP_LESS_EQUAL; break;
			case TK_OP_GREATER: op = Variant::OP_GREATER; break;
			case TK_OP_GREATER_EQUAL: op = Variant::OP_GREATER_EQUAL; break;
			case TK_OP_AND: op = Variant::OP_AND; break;
			case TK_OP_OR: op = Variant::OP_OR; break;
			case TK_OP_NOT: op = Variant::OP_NOT; break;
			case TK_OP_ADD: op = Variant::OP_ADD; break;
			case TK_OP_SUB: op = Variant::OP_SUBTRACT; break;
			case TK_OP_MUL: op = Variant::OP_MULTIPLY; break;
			case TK_OP_DIV: op = Variant::OP_DIVIDE; break;
			case TK_OP_MOD: op = Variant::OP_MODULE; break;
			case TK_OP_SHIFT_LEFT: op = Variant::OP_SHIFT_LEFT; break;
			case TK_OP_SHIFT_RIGHT: op = Variant::OP_SHIFT_RIGHT; break;
			case TK_OP_BIT_AND: op = Variant::OP_BIT_AND; break;
			case TK_OP_BIT_OR: op = Variant::OP_BIT_OR; break;
			case TK_OP_BIT_XOR: op = Variant::OP_BIT_XOR; break;
			case TK_OP_BIT_INVERT: op = Variant::OP_BIT_NEGATE; break;
			default: {};
		}

		if (op == Variant::OP_MAX) { //stop appending stuff
			str_ofs = cofs;
			break;
		}

		//push operator and go on
		{
			ExpressionNode e;
			e.is_op = true;
			e.op = op;
			expression.push_back(e);
		}
	}

	/* Reduce the set set of expressions and place them in an operator tree, respecting precedence */

	while (expression.size() > 1) {

		int next_op = -1;
		int min_priority = 0xFFFFF;
		bool is_unary = false;

		for (int i = 0; i < expression.size(); i++) {

			if (!expression[i].is_op) {

				continue;
			}

			int priority;

			bool unary = false;

			switch (expression[i].op) {

				case Variant::OP_BIT_NEGATE:
					priority = 0;
					unary = true;
					break;
				case Variant::OP_NEGATE:
					priority = 1;
					unary = true;
					break;

				case Variant::OP_MULTIPLY: priority = 2; break;
				case Variant::OP_DIVIDE: priority = 2; break;
				case Variant::OP_MODULE: priority = 2; break;

				case Variant::OP_ADD: priority = 3; break;
				case Variant::OP_SUBTRACT: priority = 3; break;

				case Variant::OP_SHIFT_LEFT: priority = 4; break;
				case Variant::OP_SHIFT_RIGHT: priority = 4; break;

				case Variant::OP_BIT_AND: priority = 5; break;
				case Variant::OP_BIT_XOR: priority = 6; break;
				case Variant::OP_BIT_OR: priority = 7; break;

				case Variant::OP_LESS: priority = 8; break;
				case Variant::OP_LESS_EQUAL: priority = 8; break;
				case Variant::OP_GREATER: priority = 8; break;
				case Variant::OP_GREATER_EQUAL: priority = 8; break;

				case Variant::OP_EQUAL: priority = 8; break;
				case Variant::OP_NOT_EQUAL: priority = 8; break;

				case Variant::OP_IN: priority = 10; break;

				case Variant::OP_NOT:
					priority = 11;
					unary = true;
					break;
				case Variant::OP_AND: priority = 12; break;
				case Variant::OP_OR: priority = 13; break;

				default: {
					_set_error("Parser bug, invalid operator in expression: " + itos(expression[i].op));
					return NULL;
				}
			}

			if (priority < min_priority) {
				// < is used for left to right (default)
				// <= is used for right to left

				next_op = i;
				min_priority = priority;
				is_unary = unary;
			}
		}

		if (next_op == -1) {

			_set_error("Yet another parser bug....");
			ERR_FAIL_COND_V(next_op == -1, NULL);
		}

		// OK! create operator..
		if (is_unary) {

			int expr_pos = next_op;
			while (expression[expr_pos].is_op) {

				expr_pos++;
				if (expr_pos == expression.size()) {
					//can happen..
					_set_error("Unexpected end of expression...");
					return NULL;
				}
			}

			//consecutively do unary opeators
			for (int i = expr_pos - 1; i >= next_op; i--) {

				OperatorNode *op = alloc_node<OperatorNode>();
				op->op = expression[i].op;
				op->nodes[0] = expression[i + 1].node;
				op->nodes[1] = NULL;
				expression.write[i].is_op = false;
				expression.write[i].node = op;
				expression.remove(i + 1);
			}

		} else {

			if (next_op < 1 || next_op >= (expression.size() - 1)) {
				_set_error("Parser bug...");
				ERR_FAIL_V(NULL);
			}

			OperatorNode *op = alloc_node<OperatorNode>();
			op->op = expression[next_op].op;

			if (expression[next_op - 1].is_op) {

				_set_error("Parser bug...");
				ERR_FAIL_V(NULL);
			}

			if (expression[next_op + 1].is_op) {
				// this is not invalid and can really appear
				// but it becomes invalid anyway because no binary op
				// can be followed by a unary op in a valid combination,
				// due to how precedence works, unaries will always disappear first

				_set_error("Unexpected two consecutive operators.");
				return NULL;
			}

			op->nodes[0] = expression[next_op - 1].node; //expression goes as left
			op->nodes[1] = expression[next_op + 1].node; //next expression goes as right

			//replace all 3 nodes by this operator and make it an expression
			expression.write[next_op - 1].node = op;
			expression.remove(next_op);
			expression.remove(next_op);
		}
	}

	return expression[0].node;
}
Exemplo n.º 27
0
int ConnectBrokenFunctionChunk(ea_t address)
{
	int connected_links_count=0;
	func_t *func=get_func(address);
	char function_name[1024]={0,};
	get_func_name(address,function_name,sizeof(function_name));

	bool is_function=false;
	bool AddFunctionAsMemberOfFunction=false;

	ea_t cref=get_first_cref_to(address);
	while(cref!=BADADDR)
	{
		func_t *cref_func=get_func(cref);
		if(cref_func!=func)
		{
			char op_buffer[40]={0,};
			ua_mnem(cref,op_buffer,sizeof(op_buffer));
			if(cmd.itype==NN_call || cmd.itype==NN_callfi || cmd.itype==NN_callni)
			{
				is_function=true;
				break;
			}
		}
		cref=get_next_cref_to(address,cref);
	}

	if(!is_function)
	{
		if(func)
			del_func(address);	
		cref=get_first_cref_to(address);
		while(cref!=BADADDR)
		{
			func_t *cref_func=get_func(cref);
			if(cref_func)
			{
				char cref_function_name[1024];
				get_func_name(cref,cref_function_name,sizeof(cref_function_name));
				msg("Adding Location %s(%x) To Function Member Of %s(%x:%x)\n",function_name,address,cref_function_name,cref_func->startEA,cref);
				append_func_tail(cref_func,address,GetBlockEnd(address));
				connected_links_count++;
			}
			cref=get_next_cref_to(address,cref);
		}
	}else if(AddFunctionAsMemberOfFunction)
	{
		cref=get_first_cref_to(address);
		while(cref!=BADADDR)
		{
			char op_buffer[40]={0,};
			ua_mnem(cref,op_buffer,sizeof(op_buffer));
			if(!(cmd.itype==NN_call || cmd.itype==NN_callfi || cmd.itype==NN_callni))
			{
				func_t *cref_func=get_func(cref);
				if(cref_func)
				{
					char cref_function_name[1024];
					get_func_name(cref,cref_function_name,sizeof(cref_function_name));
					msg("Adding Function %s(%x) To Function Member Of %s(%x:%x)\n",function_name,address,cref_function_name,cref_func->startEA,cref);
					append_func_tail(cref_func,address,GetBlockEnd(address));
					connected_links_count++;
				}
			}
			cref=get_next_cref_to(address,cref);
		}
	}
	return connected_links_count;
}
Exemplo n.º 28
0
/*
 * GetStreamScanPlan
 */
ForeignScan *
GetStreamScanPlan(PlannerInfo *root, RelOptInfo *baserel,
                  Oid relid, ForeignPath *best_path, List *tlist, List *scan_clauses, Plan *outer_plan)
{
    StreamFdwInfo *sinfo = (StreamFdwInfo *) baserel->fdw_private;
    List *physical_tlist = build_physical_tlist(root, baserel);
    RangeTblEntry *rte = NULL;
    int i;
    TableSampleClause *sample;
    Value *sample_cutoff = NULL;

    /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    scan_clauses = extract_actual_clauses(scan_clauses, false);

    for (i = 1; i <= root->simple_rel_array_size; i++)
    {
        rte = root->simple_rte_array[i];
        if (rte && rte->relid == relid)
            break;
    }

    if (!rte || rte->relid != relid)
        elog(ERROR, "stream RTE missing");

    sample = rte->tablesample;
    if (sample)
    {
        double dcutoff;
        Datum d;
        ExprContext *econtext;
        bool isnull;
        Node *node;
        Expr *expr;
        ExprState *estate;
        ParseState *ps = make_parsestate(NULL);
        float4 percent;

        if (sample->tsmhandler != BERNOULLI_OID)
            ereport(ERROR,
                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                     errmsg("tablesample method %s is not supported by streams", get_func_name(sample->tsmhandler)),
                     errhint("Only bernoulli tablesample method can be used with streams.")));

        if (sample->repeatable)
            ereport(ERROR,
                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                     errmsg("streams don't support the REPEATABLE clause for tablesample")));

        econtext = CreateStandaloneExprContext();

        ps = make_parsestate(NULL);
        node = (Node *) linitial(sample->args);
        node = transformExpr(ps, node, EXPR_KIND_OTHER);
        expr = expression_planner((Expr *) node);

        estate = ExecInitExpr(expr, NULL);
        d = ExecEvalExpr(estate, econtext, &isnull, NULL);

        free_parsestate(ps);
        FreeExprContext(econtext, false);

        percent = DatumGetFloat4(d);
        if (percent < 0 || percent > 100 || isnan(percent))
            ereport(ERROR,
                    (errcode(ERRCODE_INVALID_TABLESAMPLE_ARGUMENT),
                     errmsg("sample percentage must be between 0 and 100")));

        dcutoff = rint(((double) RAND_MAX + 1) * percent / 100);
        sample_cutoff = makeInteger((int) dcutoff);
    }

    return make_foreignscan(tlist, scan_clauses, baserel->relid,
                            NIL, list_make3(sinfo->colnames, physical_tlist, sample_cutoff), NIL, NIL, outer_plan);
}
Exemplo n.º 29
0
/*
 * init_sexpr - initialize a SetExprState node during first use
 */
static void
init_sexpr(Oid foid, Oid input_collation, Expr *node,
		   SetExprState *sexpr, PlanState *parent,
		   MemoryContext sexprCxt, bool allowSRF, bool needDescForSRF)
{
	AclResult	aclresult;

	/* Check permission to call function */
	aclresult = pg_proc_aclcheck(foid, GetUserId(), ACL_EXECUTE);
	if (aclresult != ACLCHECK_OK)
		aclcheck_error(aclresult, OBJECT_FUNCTION, get_func_name(foid));
	InvokeFunctionExecuteHook(foid);

	/*
	 * Safety check on nargs.  Under normal circumstances this should never
	 * fail, as parser should check sooner.  But possibly it might fail if
	 * server has been compiled with FUNC_MAX_ARGS smaller than some functions
	 * declared in pg_proc?
	 */
	if (list_length(sexpr->args) > FUNC_MAX_ARGS)
		ereport(ERROR,
				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
				 errmsg_plural("cannot pass more than %d argument to a function",
							   "cannot pass more than %d arguments to a function",
							   FUNC_MAX_ARGS,
							   FUNC_MAX_ARGS)));

	/* Set up the primary fmgr lookup information */
	fmgr_info_cxt(foid, &(sexpr->func), sexprCxt);
	fmgr_info_set_expr((Node *) sexpr->expr, &(sexpr->func));

	/* Initialize the function call parameter struct as well */
	InitFunctionCallInfoData(sexpr->fcinfo_data, &(sexpr->func),
							 list_length(sexpr->args),
							 input_collation, NULL, NULL);

	/* If function returns set, check if that's allowed by caller */
	if (sexpr->func.fn_retset && !allowSRF)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("set-valued function called in context that cannot accept a set"),
				 parent ? executor_errposition(parent->state,
											   exprLocation((Node *) node)) : 0));

	/* Otherwise, caller should have marked the sexpr correctly */
	Assert(sexpr->func.fn_retset == sexpr->funcReturnsSet);

	/* If function returns set, prepare expected tuple descriptor */
	if (sexpr->func.fn_retset && needDescForSRF)
	{
		TypeFuncClass functypclass;
		Oid			funcrettype;
		TupleDesc	tupdesc;
		MemoryContext oldcontext;

		functypclass = get_expr_result_type(sexpr->func.fn_expr,
											&funcrettype,
											&tupdesc);

		/* Must save tupdesc in sexpr's context */
		oldcontext = MemoryContextSwitchTo(sexprCxt);

		if (functypclass == TYPEFUNC_COMPOSITE ||
			functypclass == TYPEFUNC_COMPOSITE_DOMAIN)
		{
			/* Composite data type, e.g. a table's row type */
			Assert(tupdesc);
			/* Must copy it out of typcache for safety */
			sexpr->funcResultDesc = CreateTupleDescCopy(tupdesc);
			sexpr->funcReturnsTuple = true;
		}
		else if (functypclass == TYPEFUNC_SCALAR)
		{
			/* Base data type, i.e. scalar */
			tupdesc = CreateTemplateTupleDesc(1, false);
			TupleDescInitEntry(tupdesc,
							   (AttrNumber) 1,
							   NULL,
							   funcrettype,
							   -1,
							   0);
			sexpr->funcResultDesc = tupdesc;
			sexpr->funcReturnsTuple = false;
		}
		else if (functypclass == TYPEFUNC_RECORD)
		{
			/* This will work if function doesn't need an expectedDesc */
			sexpr->funcResultDesc = NULL;
			sexpr->funcReturnsTuple = true;
		}
		else
		{
			/* Else, we will fail if function needs an expectedDesc */
			sexpr->funcResultDesc = NULL;
		}

		MemoryContextSwitchTo(oldcontext);
	}
	else
		sexpr->funcResultDesc = NULL;

	/* Initialize additional state */
	sexpr->funcResultStore = NULL;
	sexpr->funcResultSlot = NULL;
	sexpr->shutdown_reg = false;
}