void write_system_call( FILE *file, struct function *f ) { if( f->options->indirect ) { fprintf(file,"\t\t\t#ifdef SYS_%s\n",f->options->indirect->text); if(!is_void(f->type)) { fprintf(file,"\t\t\t\tresult = "); } else { fprintf(file,"\t\t\t\t"); } if(f->params) { fprintf(file,"syscall(SYS_%s,SYS_%s,%s);\n",f->options->indirect->text,upper_string(f->name->text),arg_string(f->params)); } else { fprintf(file,"syscall(SYS_%s,SYS_%s);\n",f->options->indirect->text,upper_string(f->name->text)); } } else { fprintf(file,"\t\t\t#ifdef SYS_%s\n",pattern_complete(f->options->local_name->text,f->name->text)); if(!is_void(f->type)) { fprintf(file,"\t\t\t\tresult = "); } else { fprintf(file,"\t\t\t\t"); } if(f->params) { fprintf(file,"syscall(SYS_%s,%s);\n",pattern_complete(f->options->local_name->text,f->name->text),arg_string(f->params)); } else { fprintf(file,"syscall(SYS_%s);\n",pattern_complete(f->options->local_name->text,f->name->text)); } } fprintf(file,"\t\t\t#else\n"); write_dynamic_call( file, f ); fprintf(file,"\t\t\t#endif\n"); }
void generate_entry( FILE *file, struct function *f, char *entry ) { fprintf(file,"extern \"C\" %s %s( %s )\n{\n",type_string(f->type),entry,param_string(f->params)); fprintf(file,"\t%s (*fptr)(%s);\n",type_string(f->type),param_string(f->params)); if(!is_void(f->type)) { fprintf(file,"\t%s result;\n",type_string(f->type)); } write_vararg_decls( file, f->params ); fprintf(file,"\tbypass_layer_init();\n"); // PZK 8/7/07: changed int to intptr_t for 64-bit compatibility fprintf(file,"\tfptr = (%s(*)(%s)) layer_lookup( \"bypass_agent_action_%s\", \"%s\", (intptr_t) %s );\n",type_string(f->type),param_string(f->params),f->name->text,entry,entry); fprintf(file,"\tif(!fptr) fptr = %s;\n",entry); fprintf(file,"\tlayer_descend();\n"); if(!is_void(f->type)) { fprintf(file,"\tresult = "); } else { fprintf(file,"\t"); } fprintf(file,"(*fptr) ( %s );\n",arg_string(f->params)); fprintf(file,"\tlayer_ascend();\n"); if(!is_void(f->type)) { fprintf(file,"\treturn result;\n"); } /* special case: a switch for _exit() or exit() must fall back on a fatal message */ if(!strcmp(f->name->text,"exit") || !strcmp(f->name->text,"_exit") ) { fprintf(file,"\tbypass_fatal(\"exit() returned without exiting!\");\n"); } fprintf(file,"}\n\n"); }
void pwn::postfix_writer::do_simple_lvalue_node(pwn::simple_lvalue_node * const node, int lvl) { CHECK_TYPES(_compiler, _symtab, node); std::string id = fix_id(node->value()); std::shared_ptr<pwn::symbol> symbol = _symtab.find(id); if ( ! _current_function) { // global context if ( ! symbol->is_var()) { throw "Error: assigning a value to a function"; } _pf.ADDR(id); } else { // local context bool is_return_symbol = ( ! symbol->is_var()) // the symbol is a function && (_current_function->name() == symbol->name()) // the symbol has the same name as the current function && ( ! is_void(_current_function->type())); // the function doesnt "return" void if (is_return_symbol) { if (is_double(_current_function->type())) { _pf.LOCAL(-8); // double @ -8 } else { _pf.LOCAL(-4); // int, string, pointer @ -4 } } else if (symbol->is_var() && symbol->name() != _current_function->name()) { _pf.LOCAL(symbol->offset()); } else { throw "Error: invalid left value"; } } }
static int parse_line(char *line, char **name, char **ret, char **param) { if (*line == '#' || (*name = strsep(&line, ":")) == NULL) return 0; *ret = strsep(&line, ":"); *param = strsep(&line, ":"); if (is_void(*ret)) *ret = NULL; if (is_void(*param)) *param = NULL; return 1; }
void write_no_local_call( FILE *file, struct function *f ) { if(!is_void(f->type)) { fprintf(file,"\t\t\t\tresult = "); } else { fprintf(file,"\t\t\t\t"); } fprintf(file,"bypass_call_error(BYPASS_CALL_%s,\"no local version of this call\");\n",pattern_complete(f->options->remote_name->text,f->name->text)); }
// // is_void // static bool is_void(VariableType const *type) { if (type->getBasicType() == VariableType::BT_VOID) return true; if (type->getBasicType() == VariableType::BT_ARR) return is_void(type->getReturn()); return false; }
void write_static_call( FILE *file, struct function *f ) { fprintf(file,"\t\t\textern %s %s (%s);\n",type_string(f->type),upper_string(pattern_complete(f->options->local_name->text,f->name->text)),param_string(f->params)); if(!is_void(f->type)) { fprintf(file,"\t\t\tresult = "); } else { fprintf(file,"\t\t\t"); } fprintf(file,"%s( %s );\n",upper_string(pattern_complete(f->options->local_name->text,f->name->text)),arg_string(f->params)); }
static size_t get_return_struct(code_system *system, type *return_type) { if (is_void(return_type)) { return 0; } size_t count = system->struct_count; code_struct *return_struct; for (size_t i = 0; i < count; i++) { return_struct = get_code_struct(system, i); if (return_struct->field_count != 1) { continue; } code_field *first_field = &return_struct->fields[0]; type *first = first_field->field_type; if (first->type != T_BLOCKREF || !first->blocktype || !first->blocktype->next || first->blocktype->next->next) { continue; } type *second = first->blocktype->next->argument_type; first = first->blocktype->argument_type; if (first->type == T_OBJECT && first->struct_index == i && equivalent_type(return_type, second)) { return i; } } return_struct = add_struct(system); return_struct->field_count = 1; return_struct->fields = xmalloc(sizeof(code_field)); return_struct->fields[0].field_type = new_type(T_BLOCKREF); argument *blocktype = xmalloc(sizeof(*blocktype)); blocktype->symbol_name = NULL; blocktype->argument_type = get_object_type(count); return_struct->fields[0].field_type->blocktype = blocktype; blocktype->next = xmalloc(sizeof(argument)); blocktype = blocktype->next; blocktype->symbol_name = NULL; blocktype->argument_type = copy_type(return_type); blocktype->next = NULL; return count; }
void generate_shadow_action( FILE *file, struct function *f ) { fprintf(file,"static %s bypass_shadow_action_%s( %s )\n{\n",type_string(f->type),f->name->text,param_string_noconst(f->params)); write_vararg_decls(file,f->params); if(f->shadow_action) { fprintf(file,"%s\n",f->shadow_action->text ); } else { if(!is_void(f->type)) { fprintf(file,"\treturn "); } fprintf(file,"%s( %s );\n",f->name->text,arg_string_noconst(f->params)); } fprintf(file,"\n}\n\n"); }
/* FOLLOW(parameter-list) = { ')' }, peek to return empty list; even though K&R * require at least specifier: (void) * Set parameter-type-list = parameter-list, including the , ... */ static struct typetree *parameter_list(const struct typetree *base) { struct typetree *func = type_init(T_FUNCTION); func->next = base; while (peek().token != ')') { const char *name = NULL; struct typetree *type; type = declaration_specifiers(NULL); type = declarator(type, &name); if (is_void(type)) { if (nmembers(func)) { error("Incomplete type in parameter list."); } break; } type_add_member(func, name, type); if (peek().token != ',') { break; } consume(','); if (peek().token == ')') { error("Unexpected trailing comma in parameter list."); exit(1); } else if (peek().token == DOTS) { consume(DOTS); assert(!is_vararg(func)); type_add_member(func, "...", NULL); assert(is_vararg(func)); break; } } return func; }
void write_dynamic_call( FILE *file, struct function *f ) { /* Declare a library handle, open it if needed */ fprintf(file,"\t\t\tstatic void *handle = 0;\n"); fprintf(file,"\t\t\tif(!handle) handle = bypass_library_open(\"%s.so\");\n",f->options->library->text); fprintf(file,"\t\t\tif(!handle) handle = bypass_library_open(\"%s.sl\");\n",f->options->library->text); fprintf(file,"\t\t\tif(!handle) handle = bypass_library_open(\"%s.so.6\");\n",f->options->library->text); fprintf(file,"\t\t\tif(!handle) bypass_call_error(BYPASS_CALL_%s,\"can't find library\");\n\n",f->name->text); /* Declare a function pointer, look it up if needed */ fprintf(file,"\t\t\tstatic %s (*fptr)( %s ) = 0;\n",type_string(f->type),param_string(f->params)); fprintf(file,"\t\t\tif(!fptr) fptr = (%s(*)(%s)) bypass_library_lookup(handle,\"%s\");\n",type_string(f->type),param_string(f->params),pattern_complete(f->options->local_name->text,f->name->text)); fprintf(file,"\t\t\tif(!fptr) bypass_call_error(BYPASS_CALL_%s,\"can't find procedure in library\");\n",f->name->text); /* Otherwise, invoke the function */ if(!is_void(f->type)) { fprintf(file,"\t\t\tresult = "); } else { fprintf(file,"\t\t\t"); } fprintf(file,"fptr( %s );\n",arg_string(f->params)); }
void generate_agent_action( FILE *file, struct function *f ) { fprintf(file,"extern \"C\" %s bypass_agent_action_%s( %s )\n{\n",type_string(f->type),f->name->text,param_string(f->params)); write_vararg_decls(file,f->params); if(f->agent_action) { fprintf(file,"\t%s\n",f->agent_action->text ); } else { if(!is_void(f->type)) { fprintf(file,"\treturn "); } fprintf(file,"bypass_shadow_%s( %s );\n",pattern_complete(f->options->remote_name->text,f->name->text),arg_string_noconst(f->params)); } fprintf(file,"\n}\n\n"); if( f->options->instead ) { generate_agent_action( file, f->options->instead ); } }
static void generate_return(code_block *parent, return_statement *ret) { function *fn = ret->target; bool non_void = !is_void(fn->return_type); if (non_void == !ret->value) { fprintf(stderr, "return from void function with return or non-void without " "return\n"); abort(); } size_t param_count = 1 + non_void; if (non_void) { parent = generate_expression(parent, ret->value); } parent->tail.type = GOTO; parent->tail.parameter_count = param_count; parent->tail.parameters = xmalloc(sizeof(size_t) * param_count); if (non_void) { parent->tail.parameters[1] = last_instruction(parent); } parent->tail.parameters[0] = 0; parent->tail.first_block = next_instruction(parent); size_t return_index = instruction_type(parent, 0)->struct_index; code_struct *return_struct = get_code_struct(parent->system, return_index); type *return_block_type = return_struct->fields[0].field_type; code_instruction *unwrap = new_instruction(parent, 2); unwrap->operation.type = O_GET_FIELD; unwrap->type = copy_type(return_block_type); unwrap->parameters[0] = 0; // return structs are always the first argument unwrap->parameters[1] = 0; // blockref position in all return structs }
// // make_var // static SourceExpression::Pointer make_var(SourceTokenizerC *in, SourceContext *context, LinkageSpecifier linkSpec, SourcePosition const &pos, std::string const &nameSrc, VariableType::Reference type, StoreData const &store, bool externDef) { SourceExpression::Pointer initExpr; SourceVariable::Pointer var; ObjectExpression::Pointer addr; if (in->peekType(SourceTokenC::TT_AT)) { in->get(); addr = SourceExpressionDS::make_prefix(in, context)->makeObject(); } // Generate object name. std::string nameObj; switch (linkSpec) { case LINKAGE_INTERN: nameObj = context->getLabel() + nameSrc; break; case LINKAGE_ACS: nameObj = nameSrc; break; case LINKAGE_C: nameObj = "_" + nameSrc; break; case LINKAGE_CPP: case LINKAGE_DS: nameObj = context->getLabelNamespace() + nameSrc; break; } // Generate expression (unless final type is determined later). SourceExpression::Pointer expr; if(!is_array_length_zero(type) && !is_void(type) && !is_autoptr(type)) expr = add_var(context, linkSpec, pos, nameSrc, nameObj, type, store, addr, externDef, var); // Variable initialization. (But not for external declaration.) if (!externDef && in->peekType(SourceTokenC::TT_EQUALS)) { SourceExpression::Pointer initSrc; ObjectExpression::Pointer initObj; in->get(SourceTokenC::TT_EQUALS); initSrc = SourceExpressionDS::make_assignment(in, context); // Automatic type. if (is_void(type)) { if (type->getBasicType() == VariableType::BT_VOID) type = initSrc->getType(); else { VariableType::Reference initSrcType = initSrc->getType(); if (initSrcType->getBasicType() != VariableType::BT_BLOCK) Error_P("expected BT_BLOCK"); type = get_void(type, initSrcType); type = get_array_length(type, initSrcType); } expr = add_var(context, linkSpec, pos, nameSrc, nameObj, type, store, addr, externDef, var); } // Initializer-determined array length. else if(is_array_length_zero(type)) { VariableType::Reference initSrcType = initSrc->getType(); if(initSrcType->getBasicType() == VariableType::BT_BLOCK) { type = get_array_length(type, initSrcType); } else if(initSrcType->getBasicType() == VariableType::BT_STR) { std::string initStr = initSrc->makeObject()->resolveString(); type = type->getReturn()->getArray(initStr.size()); initSrcType = initSrcType->getReturn()->getArray(initStr.size()); initSrc = SourceExpression:: create_value_cast_force(initSrc, initSrcType, context, pos); } else Error_P("expected block or string"); expr = add_var(context, linkSpec, pos, nameSrc, nameObj, type, store, addr, externDef, var); } // Initializer-determined storage. else if(is_autoptr(type)) { VariableType::Reference initSrcType = initSrc->getType(); if(initSrcType->getBasicType() == VariableType::BT_PTR) { initSrcType = initSrcType->getReturn(); type = type->getReturn() ->setStorage(initSrcType->getStoreType(), initSrcType->getStoreArea()) ->getPointer(); } expr = add_var(context, linkSpec, pos, nameSrc, nameObj, type, store, addr, externDef, var); } // Cast initSrc to the new object's type. initSrc = SourceExpression:: create_value_cast_implicit(initSrc, type, context, pos); // Generate initObj here in case one of the above rules alters initSrc. if(initSrc->canMakeObject()) initObj = initSrc->makeObject(); // Generate expression to set variable. SourceExpression::Pointer exprSet = SourceExpression:: create_binary_assign_const(expr, initSrc, context, pos); switch (store.type) { case STORE_MAPREGISTER: if(!initObj || Target == TARGET_Hexen) goto case_init; if(!ObjectData::Register::InitMap(nameObj, type, initObj)) goto case_init; break; case STORE_MAPARRAY: if(!initObj) goto case_init; if(!ObjectData::ArrayVar::InitMap(nameObj, type, initObj)) goto case_init; break; case STORE_WORLDARRAY: case STORE_GLOBALARRAY: case STORE_STATIC: case_init: { if(!initExpr) initExpr = MakeInit(context, pos, var, nameObj, store, false); // Generate expression of value if initialized. SourceExpression::Pointer initVal = SourceExpression:: create_value_int(1, context, pos); // Generate expression to set flag. SourceExpression::Pointer initSet = SourceExpression:: create_binary_assign(initExpr, initVal, context, pos); // Generate expression to check if initialized. SourceExpression::Pointer initChk = SourceExpression:: create_branch_not(initExpr, context, pos); // Generate expression to set variable and flag. SourceExpression::Vector initBothVector; initBothVector.push_back(exprSet); initBothVector.push_back(initSet); SourceExpression::Pointer initBoth = SourceExpression:: create_value_block(initBothVector, context, pos); // Generate expression to conditionally set variable and flag. expr = SourceExpression:: create_branch_if(initChk, initBoth, context, pos); } break; default: expr = exprSet; break; } } // If not done yet, add var now. if (!expr) expr = add_var(context, linkSpec, pos, nameSrc, nameObj, type, store, addr, externDef, var); // Need to always generate the init var for array storage. if((store.type == STORE_MAPARRAY || store.type == STORE_WORLDARRAY || store.type == STORE_GLOBALARRAY) && !initExpr) { initExpr = MakeInit(context, pos, var, nameObj, store, externDef); } return expr; }
static void write_function_stubs(type_t *iface, unsigned int *proc_offset) { const func_t *func; const var_t *var; const var_t* explicit_handle_var; if (!iface->funcs) return; LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) { const var_t *def = func->def; int has_full_pointer = is_full_pointer_function(func); /* check for a defined binding handle */ explicit_handle_var = get_explicit_handle_var(func); fprintf(server, "void __RPC_STUB\n"); fprintf(server, "%s_", iface->name); write_name(server, def); fprintf(server, "(\n"); indent++; print_server("PRPC_MESSAGE _pRpcMessage)\n"); indent--; /* write the functions body */ fprintf(server, "{\n"); indent++; /* Declare arguments */ declare_stub_args(server, indent, func); print_server("MIDL_STUB_MESSAGE _StubMsg;\n"); print_server("RPC_STATUS _Status;\n"); fprintf(server, "\n"); print_server("((void)(_Status));\n"); print_server("NdrServerInitializeNew(\n"); indent++; print_server("_pRpcMessage,\n"); print_server("&_StubMsg,\n"); print_server("&%s_StubDesc);\n", iface->name); indent--; fprintf(server, "\n"); write_parameters_init(server, indent, func); if (explicit_handle_var) { print_server("%s = _pRpcMessage->Handle;\n", explicit_handle_var->name); fprintf(server, "\n"); } print_server("RpcTryFinally\n"); print_server("{\n"); indent++; print_server("RpcTryExcept\n"); print_server("{\n"); indent++; if (has_full_pointer) write_full_pointer_init(server, indent, func, TRUE); if (func->args) { print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n"); indent++; print_server("NdrConvert(\n"); indent++; print_server("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); print_server("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", *proc_offset); indent -= 2; fprintf(server, "\n"); /* unmarshall arguments */ write_remoting_arguments(server, indent, func, PASS_IN, PHASE_UNMARSHAL); } print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n"); print_server("{\n"); indent++; print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); indent--; print_server("}\n"); indent--; print_server("}\n"); print_server("RpcExcept(RPC_BAD_STUB_DATA_EXCEPTION_FILTER)\n"); print_server("{\n"); indent++; print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); indent--; print_server("}\n"); print_server("RpcEndExcept\n"); fprintf(server, "\n"); /* Assign 'out' arguments */ assign_stub_out_args(server, indent, func); /* Call the real server function */ if (!is_void(get_func_return_type(func))) print_server("_RetVal = "); else print_server(""); write_prefix_name(server, prefix_server, def); if (func->args) { int first_arg = 1; fprintf(server, "(\n"); indent++; LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) { if (first_arg) first_arg = 0; else fprintf(server, ",\n"); if (is_context_handle(var->type)) { /* if the context_handle attribute appears in the chain of types * without pointers being followed, then the context handle must * be direct, otherwise it is a pointer */ int is_ch_ptr = is_aliaschain_attr(var->type, ATTR_CONTEXTHANDLE) ? FALSE : TRUE; print_server("("); write_type_decl_left(server, var->type); fprintf(server, ")%sNDRSContextValue(%s)", is_ch_ptr ? "" : "*", var->name); } else { print_server(""); if (var->type->declarray) fprintf(server, "*"); write_name(server, var); } } fprintf(server, ");\n"); indent--; } else {
char *get_token(char *lexeme , int mode){ char *token=(char*)calloc(strlen(lexeme)+50,sizeof(char)); //printf("Getting token\n"); if(is_long(lexeme)){ sprintf(token,"%d",LONG); } else if(is_static(lexeme)){ sprintf(token,"%d",STATIC); } else if(is_union(lexeme)){ sprintf(token,"%d",UNION); } else if(is_default(lexeme)){ sprintf(token,"%d",DEFAULT); } else if(is_break(lexeme)){ sprintf(token,"%d",BREAK); } else if(is_case(lexeme)){ sprintf(token,"%d",CASE); } else if(is_continue(lexeme)){ sprintf(token,"%d",CONTINUE); } else if(is_goto(lexeme)){ sprintf(token,"%d",GOTO); } else if(is_struct(lexeme)){ sprintf(token,"%d",STRUCT); } else if(is_const(lexeme)){ sprintf(token,"%d",CONST); } else if(is_void(lexeme)){ sprintf(token,"%d",VOID); } else if(is_switch(lexeme)){ sprintf(token,"%d",SWITCH); } else if(is_for(lexeme)){ sprintf(token,"%d",FOR); } else if(is_while(lexeme)){ sprintf(token,"%d",WHILE); } else if(is_do(lexeme)){ sprintf(token,"%d",DO); } else if(is_return(lexeme)){ sprintf(token,"%d",RETURN); } else if(is_bool(lexeme)){ sprintf(token,"%d",BOOL); } else if(is_char(lexeme)){ sprintf(token,"%d",CHAR); } else if(is_signed(lexeme)){ sprintf(token,"%d",SIGNED); } else if(is_unsigned(lexeme)){ sprintf(token,"%d",UNSIGNED); } else if(is_short(lexeme)){ sprintf(token,"%d",SHORT); } else if(is_int(lexeme)){ sprintf(token,"%d",INT); } else if(is_float(lexeme)){ sprintf(token,"%d",FLOAT); } else if(is_double(lexeme)){ sprintf(token,"%d",DOUBLE); } else if(is_l_square(lexeme)){ sprintf(token,"%d",L_SQUARE); } else if(is_r_square(lexeme)){ sprintf(token,"%d",R_SQUARE); } else if(is_l_paraen(lexeme)){ sprintf(token,"%d",L_PARAEN); } else if(is_r_paraen(lexeme)){ sprintf(token,"%d",R_PARAEN); } else if(is_l_cbrace(lexeme)){ sprintf(token,"%d",L_CBRACE); } else if(is_r_cbrace(lexeme)){ sprintf(token,"%d",R_CBRACE); } else if(is_comma(lexeme)){ sprintf(token,"%d",COMMA); } else if(is_semicol(lexeme)){ sprintf(token,"%d",SEMICOL); } else if(is_eq_eq(lexeme)){ sprintf(token,"%d",EQ_EQ); } else if(is_lesser(lexeme)){ sprintf(token,"%d",LESSER); } else if(is_less_eq(lexeme)){ sprintf(token,"%d",LESS_EQ); } else if(is_div(lexeme)){ sprintf(token,"%d",DIV); } else if(is_greater(lexeme)){ sprintf(token,"%d",GREATER); } else if(is_great_eq(lexeme)){ sprintf(token,"%d",GREAT_EQ); } else if(is_plus_eq(lexeme)){ sprintf(token,"%d",PLUS_EQ); } else if(is_minus_eq(lexeme)){ sprintf(token,"%d",MINUS_EQ); } else if(is_div_eq(lexeme)){ sprintf(token,"%d",DIV_EQ); } else if(is_mult_eq(lexeme)){ sprintf(token,"%d",MULT_EQ); } else if(is_minus_minus(lexeme)){ sprintf(token,"%d",MINUS_MINUS); } else if(is_plus_plus(lexeme)){ sprintf(token,"%d",PLUS_PLUS); } else if(is_percent(lexeme)){ sprintf(token,"%d",PERCENT); } else if(is_div(lexeme)){ sprintf(token,"%d",DIV); } else if(is_mult(lexeme)){ sprintf(token,"%d",MULT); } else if(is_minus(lexeme)){ sprintf(token,"%d",MINUS); } else if(is_plus(lexeme)){ sprintf(token,"%d",PLUS); } else if(is_int_const(lexeme)){ printf("int"); sprintf(token,"%d\t%s",INT_CONST,lexeme); } else if(is_flo_const(lexeme)){ printf("float"); sprintf(token,"%d\t%s",FLO_CONST,lexeme); } else if(is_comment_start(lexeme)){ sprintf(token,"$start"); } else if(is_comment_end(lexeme)){ sprintf(token,"$end"); } else if(is_identifier(lexeme)){ printf("Identifier"); if(mode==1) ht_set( symboltable, lexeme, "1"); sprintf(token,"%d\t%s",IDNTIFIER,lexeme); } else sprintf(token,"%d",NOTOK); return token; }
void generate_sender( FILE *file, struct function *f ) { struct param *p; char *fail_string; struct external *e; /* Create an appropriate exception handler */ if(f->type->stars) { fail_string="0"; } else if(!is_void(f->type)) { fail_string="-1"; } else { fail_string=""; } /* Write the function header */ fprintf(file,"extern \"C\" %s bypass_shadow_%s( %s )\n{\n",type_string(f->type),f->name->text,param_string_noconst(f->params)); /* Declare private bypass values */ fprintf(file,"\tstruct packet *bypass_packet=0;\n"); fprintf(file,"\tint bypass_errno=0;\n"); fprintf(file,"\tint bypass_number = BYPASS_CALL_%s;\n",f->name->text); if(!is_void(f->type)) { fprintf(file,"%s result;\n",type_string(f->type)); } write_vararg_decls(file,f->params); /* If the connection has not been made, do it now. */ fprintf(file,"\tif(!bypass_rpc_init()) goto fail;\n"); /* Start up a new packet */ fprintf(file,"\tTRY(bypass_packet = packet_create(0));\n"); /* Send the number of this call */ fprintf(file,"\tTRY(external(bypass_packet,EXTERNAL_OUT,&bypass_number));\n"); /* Send the params */ e = f->options->external; for( p=f->params; p; p=p->next ) { if( p->control->in ) { write_param( file, "bypass_packet", "EXTERNAL_OUT", p, e ); } if(e) e=e->next; } /* Finally, fire off the packet */ fprintf(file,"\tTRY(packet_put(bypass_rpc_fd_get(),bypass_packet));\n"); fprintf(file,"\tpacket_delete(bypass_packet);\n"); fprintf(file,"\tbypass_packet=0;\n\n"); /* Grab the result packet */ fprintf(file,"\tTRY(bypass_packet = packet_get(bypass_rpc_fd_get()));\n"); /* Get errno, then result, then out parameters */ fprintf(file,"\tTRY(external_errno_map(bypass_packet,EXTERNAL_IN,&bypass_errno));\n"); if(!is_void(f->type)) { fprintf(file,"\t\tTRY(external(bypass_packet,EXTERNAL_IN,&result));\n"); } e = f->options->external; for( p=f->params; p; p=p->next ) { if( p->control->out ) { write_param( file, "bypass_packet", "EXTERNAL_IN", p, e ); } if(e) e=e->next; } fprintf(file,"\tpacket_delete(bypass_packet);\n"); fprintf(file,"\terrno = bypass_errno;\n"); if(!is_void(f->type)) { fprintf(file,"\treturn result;\n"); } else { fprintf(file,"\treturn;\n"); } fprintf(file,"\n"); /* In the event of a network failure, clean up, and close the connection */ fprintf(file,"\tfail:\n"); fprintf(file,"\tbypass_errno = errno;\n"); fprintf(file,"\tif(bypass_packet) packet_delete(bypass_packet);\n"); fprintf(file,"\tbypass_rpc_close();\n"); /* If retries are turned on, put a message and sleep */ fprintf(file,"\tchar message[1024];\n"); fprintf(file,"\tsprintf(message,\"couldn't execute %%s: %%s\\n\",bypass_call_string(bypass_number),strerror(bypass_errno));\n"); fprintf(file,"\tif(bypass_failure_passthrough) {\n"); fprintf(file,"\t\tbypass_debug(message);\n"); fprintf(file,"\t} else {\n"); fprintf(file,"\t\tbypass_fatal(message);\n"); fprintf(file,"\t}\n"); fprintf(file,"\terrno = bypass_errno;\n"); fprintf(file,"\treturn %s;\n",fail_string); fprintf(file,"}\n\n"); }
static void write_function_stub(const type_t *iface, const var_t *func, unsigned int proc_offset) { const var_t *var; unsigned char explicit_fc, implicit_fc; int has_full_pointer = is_full_pointer_function(func); const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc ); if (is_interpreted_func( iface, func )) return; print_server("struct __frame_%s_%s\n{\n", iface->name, get_name(func)); indent++; print_server("__DECL_EXCEPTION_FRAME\n"); print_server("MIDL_STUB_MESSAGE _StubMsg;\n"); /* Declare arguments */ declare_stub_args(server, indent, func); indent--; print_server("};\n\n"); print_server("static void __finally_%s_%s(", iface->name, get_name(func)); fprintf(server," struct __frame_%s_%s *__frame )\n{\n", iface->name, get_name(func)); indent++; write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_FREE); if (!is_void(type_function_get_rettype(func->type))) write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_FREE); if (has_full_pointer) write_full_pointer_free(server, indent, func); indent--; print_server("}\n\n"); print_server("void __RPC_STUB %s_%s( PRPC_MESSAGE _pRpcMessage )\n", iface->name, get_name(func)); /* write the functions body */ fprintf(server, "{\n"); indent++; print_server("struct __frame_%s_%s __f, * const __frame = &__f;\n", iface->name, get_name(func)); if (has_out_arg_or_return(func)) print_server("RPC_STATUS _Status;\n"); fprintf(server, "\n"); print_server("NdrServerInitializeNew(\n"); indent++; print_server("_pRpcMessage,\n"); print_server("&__frame->_StubMsg,\n"); print_server("&%s_StubDesc);\n", iface->name); indent--; fprintf(server, "\n"); print_server( "RpcExceptionInit( __server_filter, __finally_%s_%s );\n", iface->name, get_name(func)); write_parameters_init(server, indent, func, "__frame->"); if (explicit_fc == RPC_FC_BIND_PRIMITIVE) { print_server("__frame->%s = _pRpcMessage->Handle;\n", handle_var->name); fprintf(server, "\n"); } print_server("RpcTryFinally\n"); print_server("{\n"); indent++; print_server("RpcTryExcept\n"); print_server("{\n"); indent++; if (has_full_pointer) write_full_pointer_init(server, indent, func, TRUE); if (type_get_function_args(func->type)) { print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n"); indent++; print_server("NdrConvert(&__frame->_StubMsg, (PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset); indent--; fprintf(server, "\n"); /* unmarshall arguments */ write_remoting_arguments(server, indent, func, "__frame->", PASS_IN, PHASE_UNMARSHAL); } print_server("if (__frame->_StubMsg.Buffer > __frame->_StubMsg.BufferEnd)\n"); print_server("{\n"); indent++; print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); indent--; print_server("}\n"); indent--; print_server("}\n"); print_server("RpcExcept(RPC_BAD_STUB_DATA_EXCEPTION_FILTER)\n"); print_server("{\n"); indent++; print_server("RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); indent--; print_server("}\n"); print_server("RpcEndExcept\n"); fprintf(server, "\n"); /* Assign 'out' arguments */ assign_stub_out_args(server, indent, func, "__frame->"); /* Call the real server function */ print_server("%s%s%s", is_void(type_function_get_rettype(func->type)) ? "" : "__frame->_RetVal = ", prefix_server, get_name(func)); if (type_get_function_args(func->type)) { int first_arg = 1; fprintf(server, "(\n"); indent++; LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) { if (first_arg) first_arg = 0; else fprintf(server, ",\n"); if (is_context_handle(var->type)) { /* if the context_handle attribute appears in the chain of types * without pointers being followed, then the context handle must * be direct, otherwise it is a pointer */ const char *ch_ptr = is_aliaschain_attr(var->type, ATTR_CONTEXTHANDLE) ? "*" : ""; print_server("("); write_type_decl_left(server, var->type); fprintf(server, ")%sNDRSContextValue(__frame->%s)", ch_ptr, var->name); } else { print_server("%s__frame->%s", is_array(var->type) && !type_array_is_decl_as_ptr(var->type) ? "*" : "", var->name); } } fprintf(server, ");\n"); indent--; }
static void gen_stub(type_t *iface, const var_t *func, const char *cas, unsigned int proc_offset) { const var_t *arg; int has_ret = !is_void(type_function_get_rettype(func->type)); int has_full_pointer = is_full_pointer_function(func); if (is_interpreted_func( iface, func )) return; indent = 0; print_proxy( "struct __frame_%s_%s_Stub\n{\n", iface->name, get_name(func)); indent++; print_proxy( "__DECL_EXCEPTION_FRAME\n" ); print_proxy( "MIDL_STUB_MESSAGE _StubMsg;\n"); print_proxy( "%s * _This;\n", iface->name ); declare_stub_args( proxy, indent, func ); indent--; print_proxy( "};\n\n" ); print_proxy( "static void __finally_%s_%s_Stub(", iface->name, get_name(func) ); print_proxy( " struct __frame_%s_%s_Stub *__frame )\n{\n", iface->name, get_name(func) ); indent++; write_remoting_arguments(proxy, indent, func, "__frame->", PASS_OUT, PHASE_FREE); if (has_full_pointer) write_full_pointer_free(proxy, indent, func); indent--; print_proxy( "}\n\n" ); print_proxy( "void __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(func)); indent++; print_proxy( "IRpcStubBuffer* This,\n"); print_proxy( "IRpcChannelBuffer *_pRpcChannelBuffer,\n"); print_proxy( "PRPC_MESSAGE _pRpcMessage,\n"); print_proxy( "DWORD* _pdwStubPhase)\n"); indent--; print_proxy( "{\n"); indent++; print_proxy( "struct __frame_%s_%s_Stub __f, * const __frame = &__f;\n\n", iface->name, get_name(func) ); print_proxy("__frame->_This = (%s*)((CStdStubBuffer*)This)->pvServerObject;\n\n", iface->name); /* FIXME: trace */ print_proxy("NdrStubInitialize(_pRpcMessage, &__frame->_StubMsg, &Object_StubDesc, _pRpcChannelBuffer);\n"); fprintf(proxy, "\n"); print_proxy( "RpcExceptionInit( 0, __finally_%s_%s_Stub );\n", iface->name, get_name(func) ); write_parameters_init(proxy, indent, func, "__frame->"); print_proxy("RpcTryFinally\n"); print_proxy("{\n"); indent++; if (has_full_pointer) write_full_pointer_init(proxy, indent, func, TRUE); print_proxy("if ((_pRpcMessage->DataRepresentation & 0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); indent++; print_proxy("NdrConvert( &__frame->_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset ); indent--; fprintf(proxy, "\n"); write_remoting_arguments(proxy, indent, func, "__frame->", PASS_IN, PHASE_UNMARSHAL); fprintf(proxy, "\n"); assign_stub_out_args( proxy, indent, func, "__frame->" ); print_proxy("*_pdwStubPhase = STUB_CALL_SERVER;\n"); fprintf(proxy, "\n"); print_proxy( "%s", has_ret ? "__frame->_RetVal = " : "" ); if (cas) fprintf(proxy, "%s_%s_Stub", iface->name, cas); else fprintf(proxy, "__frame->_This->lpVtbl->%s", get_name(func)); fprintf(proxy, "(__frame->_This"); if (type_get_function_args(func->type)) { LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry ) fprintf(proxy, ", %s__frame->%s", is_array(arg->type) && !type_array_is_decl_as_ptr(arg->type) ? "*" :"" , arg->name); }
static void gen_proxy(type_t *iface, const var_t *func, int idx, unsigned int proc_offset) { var_t *retval = type_function_get_retval(func->type); int has_ret = !is_void(retval->type); int has_full_pointer = is_full_pointer_function(func); const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV); const var_list_t *args = type_get_function_args(func->type); if (!callconv) callconv = "STDMETHODCALLTYPE"; indent = 0; if (is_interpreted_func( iface, func )) { if (get_stub_mode() == MODE_Oif && !is_callas( func->attrs )) return; write_type_decl_left(proxy, retval->type); print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func)); write_args(proxy, args, iface->name, 1, TRUE); print_proxy( ")\n"); write_client_call_routine( proxy, iface, func, "Object", proc_offset ); return; } print_proxy( "static void __finally_%s_%s_Proxy( struct __proxy_frame *__frame )\n", iface->name, get_name(func) ); print_proxy( "{\n"); indent++; if (has_full_pointer) write_full_pointer_free(proxy, indent, func); print_proxy( "NdrProxyFreeBuffer( __frame->This, &__frame->_StubMsg );\n" ); indent--; print_proxy( "}\n"); print_proxy( "\n"); write_type_decl_left(proxy, retval->type); print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func)); write_args(proxy, args, iface->name, 1, TRUE); print_proxy( ")\n"); print_proxy( "{\n"); indent ++; print_proxy( "struct __proxy_frame __f, * const __frame = &__f;\n" ); /* local variables */ if (has_ret) { print_proxy( "%s", "" ); write_type_decl(proxy, retval->type, retval->name); fprintf( proxy, ";\n" ); } print_proxy( "RPC_MESSAGE _RpcMessage;\n" ); if (has_ret) { if (decl_indirect(retval->type)) print_proxy("void *_p_%s = &%s;\n", retval->name, retval->name); } print_proxy( "\n"); print_proxy( "RpcExceptionInit( __proxy_filter, __finally_%s_%s_Proxy );\n", iface->name, get_name(func) ); print_proxy( "__frame->This = This;\n" ); if (has_full_pointer) write_full_pointer_init(proxy, indent, func, FALSE); /* FIXME: trace */ clear_output_vars( type_get_function_args(func->type) ); print_proxy( "RpcTryExcept\n" ); print_proxy( "{\n" ); indent++; print_proxy( "NdrProxyInitialize(This, &_RpcMessage, &__frame->_StubMsg, &Object_StubDesc, %d);\n", idx); write_pointer_checks( proxy, indent, func ); print_proxy( "RpcTryFinally\n" ); print_proxy( "{\n" ); indent++; write_remoting_arguments(proxy, indent, func, "", PASS_IN, PHASE_BUFFERSIZE); print_proxy( "NdrProxyGetBuffer(This, &__frame->_StubMsg);\n" ); write_remoting_arguments(proxy, indent, func, "", PASS_IN, PHASE_MARSHAL); print_proxy( "NdrProxySendReceive(This, &__frame->_StubMsg);\n" ); fprintf(proxy, "\n"); print_proxy( "__frame->_StubMsg.BufferStart = _RpcMessage.Buffer;\n" ); print_proxy( "__frame->_StubMsg.BufferEnd = __frame->_StubMsg.BufferStart + _RpcMessage.BufferLength;\n\n" ); print_proxy("if ((_RpcMessage.DataRepresentation & 0xffff) != NDR_LOCAL_DATA_REPRESENTATION)\n"); indent++; print_proxy("NdrConvert( &__frame->_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset ); indent--; fprintf(proxy, "\n"); write_remoting_arguments(proxy, indent, func, "", PASS_OUT, PHASE_UNMARSHAL); if (has_ret) { if (decl_indirect(retval->type)) print_proxy("MIDL_memset(&%s, 0, sizeof(%s));\n", retval->name, retval->name); else if (is_ptr(retval->type) || is_array(retval->type)) print_proxy("%s = 0;\n", retval->name); write_remoting_arguments(proxy, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL); } indent--; print_proxy( "}\n"); print_proxy( "RpcFinally\n" ); print_proxy( "{\n" ); indent++; print_proxy( "__finally_%s_%s_Proxy( __frame );\n", iface->name, get_name(func) ); indent--; print_proxy( "}\n"); print_proxy( "RpcEndFinally\n" ); indent--; print_proxy( "}\n" ); print_proxy( "RpcExcept(__frame->_StubMsg.dwStubPhase != PROXY_SENDRECEIVE)\n" ); print_proxy( "{\n" ); if (has_ret) { indent++; proxy_free_variables( type_get_function_args(func->type), "" ); print_proxy( "_RetVal = NdrProxyErrorHandler(RpcExceptionCode());\n" ); indent--; } print_proxy( "}\n" ); print_proxy( "RpcEndExcept\n" ); if (has_ret) { print_proxy( "return _RetVal;\n" ); } indent--; print_proxy( "}\n"); print_proxy( "\n"); }
void generate_receiver( FILE *file, struct function *f ) { struct param *p; struct external *e; if( strcmp(f->name->text,pattern_complete(f->options->remote_name->text,f->name->text)) ) { fprintf(file,"\t\t/* %s uses the same receiver as %s */\n\n",f->name->text,pattern_complete(f->options->remote_name->text,f->name->text)); return; } fprintf(file,"\t\tcase BYPASS_CALL_%s:\n",f->name->text); fprintf(file,"\t\t{\n"); if(!is_void(f->type)) { fprintf(file,"\t\t%s result;\n",type_string(f->type)); } /* Declare all the params */ for( p=f->params; p; p=p->next ) { fprintf(file,"\t\t%s %s=0;\n",type_string_noconst(p->type),p->name->text); } /* Get the params */ e=f->options->external; for( p=f->params; p; p=p->next ) { if( p->control->in ) { write_param( file, "bypass_packet", "EXTERNAL_IN", p, e ); } if(e) e=e->next; } /* Allocate space for any out-only parameters */ for( p=f->params; p; p=p->next ) { if( p->control->out && !p->control->in ) { write_alloc_param( file, "bypass_response", p ); } } fprintf(file,"\t\terrno = 0;\n"); /* If the function is not supported, send back an error. */ /* Otherwise, invoke the shadow action */ if( f->options->not_supported ) { fprintf(file,"\t\terrno = EINVAL;\n\n"); } else { if(!is_void(f->type)) { fprintf(file,"\t\tresult ="); } else { fprintf(file,"\t\t"); } fprintf(file,"bypass_shadow_action_%s( %s );\n",f->name->text,arg_string(f->params)); } fprintf(file,"\t\tbypass_errno = errno;\n"); /* Send back errno, then result, then out params */ fprintf(file,"\t\tTRY(external_errno_map(bypass_response,EXTERNAL_OUT,&bypass_errno));\n"); if(!is_void(f->type)) { fprintf(file,"\t\tTRY(external(bypass_response,EXTERNAL_OUT,&result));\n"); } e=f->options->external; for( p=f->params; p; p=p->next ) { if( p->control->out ) { write_param( file, "bypass_response", "EXTERNAL_OUT", p, e); } if(e) e=e->next; } /* All done. */ fprintf(file,"\t\t}\n"); fprintf(file,"\t\tbreak;\n\n"); }