bool AddressSpace::getDyninstRTLibName() { // Set the name of the dyninst RT lib if (dyninstRT_name.length() == 0) { // Get env variable if (getenv("DYNINSTAPI_RT_LIB") != NULL) { dyninstRT_name = getenv("DYNINSTAPI_RT_LIB"); } else { std::string msg = std::string("Environment variable ") + std::string("DYNINSTAPI_RT_LIB") + std::string(" has not been defined"); showErrorCallback(101, msg); return false; } } //Canonicalize name char *sptr = P_strdup(dyninstRT_name.c_str()); for (unsigned i=0; i<strlen(sptr); i++) if (sptr[i] == '/') sptr[i] = '\\'; dyninstRT_name = sptr; free(sptr); if (_access(dyninstRT_name.c_str(), 04)) { std::string msg = std::string("Runtime library ") + dyninstRT_name + std::string(" does not exist or cannot be accessed!"); showErrorCallback(101, msg); return false; } return true; }
/*Start RTP Progress Function Variable Definition: -- client_data: callback function widget Return Value: NULL */ void startRTPProgress(CLIENT_DATA *client_data){ struct sigaction handler; //sigaction structure u_int32 rcvd_buffer_size = 50 * BUFFER_SIZE; //received buffer size //Create socket for incoming connections rtp_client = setupClientUDPSocket(itoa(client_rtp_port)); if (rtp_client < 0){ showErrorCallback(client_data->window, "setupClientUDPSocket() failed: unable to connect!"); return; } //Set the received buffer size setsockopt(rtp_client, SOL_SOCKET, SO_RCVBUF, &rcvd_buffer_size, sizeof(rcvd_buffer_size)); //Set signal handler for SIGIOHandler handler.sa_handler = SIGIOHandler; //Create mask that mask all signals if (sigfillset(&handler.sa_mask) < 0){ showErrorCallback(client_data->window, "sigfillset() failed!"); return; } //No flags handler.sa_flags = 0; //Set the "SIGIO" signal if (sigaction(SIGIO, &handler, 0) < 0){ showErrorCallback(client_data->window, "sigaction() failed for SIGIO!"); return; } //We must own the socket to receive the SIGIO message if (fcntl(rtp_client, F_SETOWN, getpid()) < 0){ showErrorCallback(client_data->window, "Unable to set process owner to us!"); return; } //Arrage for nonblocking I/O and SIGIO delivery if (fcntl(rtp_client, F_SETFL, O_NONBLOCK | FASYNC) < 0){ showErrorCallback(client_data->window, "Unable to put client sock into non-blocking/async mode!"); return; } return; }
// // findVariable // scp - a BPatch_point that defines the scope of the current search // name - name of the variable to find. // BPatch_variableExpr *BPatch_image::findVariableInScope(BPatch_point &scp, const char *name) { // Get the function to search for it's local variables. // XXX - should really use more detailed scoping info here - jkh 6/30/99 BPatch_function *func = const_cast<BPatch_function *> (scp.getFunction()); if (!func) { pdstring msg = pdstring("point passed to findVariable lacks a function\n address point type passed?"); showErrorCallback(100, msg); return NULL; } BPatch_localVar *lv = func->findLocalVar(name); if (!lv) { // look for it in the parameter scope now lv = func->findLocalParam(name); } if (lv) { // create a local expr with the correct frame offset or absolute // address if that is what is needed return new BPatch_variableExpr(proc, (void *) lv->getFrameOffset(), lv->getRegister(), lv->getType(), lv->getStorageClass(), &scp); } // finally check the global scope. // return findVariable(name); /* If we have something else to try, don't report errors on this failure. */ bool reportErrors = true; char mangledName[100]; func->getName( mangledName, 100 ); char * lastScoping = NULL; if( strrchr( mangledName, ':' ) != NULL ) { reportErrors = false; } BPatch_variableExpr * gsVar = findVariable( name, reportErrors ); if( gsVar == NULL ) { /* Try finding it with the function's scope prefixed. */ if( (lastScoping = strrchr( mangledName, ':' )) != NULL ) { * (lastScoping + sizeof(char)) = '\0'; char scopedName[200]; memmove( scopedName, mangledName, strlen( mangledName ) ); memmove( scopedName + strlen( mangledName ), name, strlen( name ) ); scopedName[ strlen( mangledName ) + strlen( name ) ] = '\0'; bperr( "Searching for scoped name '%s'\n", scopedName ); gsVar = findVariable( scopedName ); } } return gsVar; }
bool process::getDyninstRTLibName() { if (dyninstRT_name.length() == 0) { // Get env variable if (getenv("DYNINSTAPI_RT_LIB") != NULL) { dyninstRT_name = getenv("DYNINSTAPI_RT_LIB"); } else { pdstring msg = pdstring( "Environment variable " + pdstring( "DYNINSTAPI_RT_LIB" ) + " has not been defined for process " ) + pdstring( getPid() ); showErrorCallback(101, msg); return false; } } // Check to see if the library given exists. if (access(dyninstRT_name.c_str(), R_OK)) { pdstring msg = pdstring("Runtime library ") + dyninstRT_name + pdstring(" does not exist or cannot be accessed!"); showErrorCallback(101, msg); return false; } return true; }
instrCodeNode *instrCodeNode::newInstrCodeNode(pdstring name_, const Focus &f, pd_process *proc, bool arg_dontInsertData, pdstring hw_cntr_str) { instrCodeNode_Val *nodeVal; // it's fine to use a code node with data inserted for a code node // that doesn't need data to be inserted pdstring key_name = instrCodeNode_Val::construct_key_name(name_, f.getName()); bool foundIt = allInstrCodeNodeVals.find(key_name, nodeVal); if(! foundIt) { HwEvent* hw = NULL; /* if PAPI isn't available, hw_cntr_str should always be "" */ if (hw_cntr_str != "") { #ifdef PAPI papiMgr* papi; papi = proc->getPapiMgr(); assert(papi); hw = papi->createHwEvent(hw_cntr_str); if (hw == NULL) { string msg = pdstring("unable to add PAPI hardware event: ") + hw_cntr_str; showErrorCallback(125, msg.c_str()); return NULL; } #endif } nodeVal = new instrCodeNode_Val(name_, f, proc, arg_dontInsertData, hw); registerCodeNodeVal(nodeVal); } nodeVal->incrementRefCount(); instrCodeNode *retNode = new instrCodeNode(nodeVal); return retNode; }
void insnCodeGen::generateBranch(codeGen &gen, long disp, bool link) { if (ABS(disp) > MAX_BRANCH) { // Too far to branch, and no proc to register trap. fprintf(stderr, "ABS OFF: 0x%lx, MAX: 0x%lx\n", ABS(disp), (unsigned long) MAX_BRANCH); bperr( "Error: attempted a branch of 0x%lx\n", disp); logLine("a branch too far\n"); showErrorCallback(52, "Internal error: branch too far"); bperr( "Attempted to make a branch of offset 0x%lx\n", disp); assert(0); } instruction insn; IFORM_OP_SET(insn, Bop); IFORM_LI_SET(insn, disp >> 2); IFORM_AA_SET(insn, 0); if (link) IFORM_LK_SET(insn, 1); else IFORM_LK_SET(insn, 0); insnCodeGen::generate(gen,insn); }
bool process::loadDYNINSTlib() { /* Look for a function we can hijack to forcibly load dyninstapi_rt. This is effectively an inferior RPC with the caveat that we're overwriting code instead of allocating memory from the RT heap. (So 'hijack' doesn't mean quite what you might think.) */ Address codeBase = findFunctionToHijack(this); if( !codeBase ) { return false; } /* glibc 2.3.4 and higher adds a fourth parameter to _dl_open(). While we could probably get away with treating the three and four -argument functions the same, check the version anyway, since we'll probably need to later. */ bool useFourArguments = true; Symbol libcVersionSymbol; if( getSymbolInfo( "__libc_version", libcVersionSymbol ) ) { char libcVersion[ sizeof( int ) * libcVersionSymbol.size() + 1 ]; libcVersion[ sizeof( int ) * libcVersionSymbol.size() ] = '\0'; if( ! readDataSpace( (void *) libcVersionSymbol.addr(), libcVersionSymbol.size(), libcVersion, true ) ) { fprintf( stderr, "%s[%d]: warning, failed to read libc version, assuming 2.3.4+\n", __FILE__, __LINE__ ); } else { startup_printf( "%s[%d]: libcVersion: %s\n", __FILE__, __LINE__, libcVersion ); /* We could potentially add a sanity check here to make sure we're looking at 2.3.x. */ int microVersion = ((int)libcVersion[4]) - ((int)'0'); if( microVersion <= 3 ) { useFourArguments = false; } } /* end if we read the version symbol */ } /* end if we found the version symbol */ if( useFourArguments ) { startup_printf( "%s[%d]: using four arguments.\n", __FILE__, __LINE__ ); } /* Fetch the name of the run-time library. */ const char DyninstEnvVar[]="DYNINSTAPI_RT_LIB"; if( ! dyninstRT_name.length() ) { // we didn't get anything on the command line if (getenv(DyninstEnvVar) != NULL) { dyninstRT_name = getenv(DyninstEnvVar); } else { pdstring msg = pdstring( "Environment variable " + pdstring( DyninstEnvVar ) + " has not been defined for process " ) + pdstring( getPid() ); showErrorCallback(101, msg); return false; } /* end if enviromental variable not found */ } /* end enviromental variable extraction */ /* Save the (main thread's) current PC.*/ savedPC = getRepresentativeLWP()->getActiveFrame().getPC(); /* _dl_open() takes three arguments: a pointer to the library name, the DLOPEN_MODE, and the return address of the current frame (that is, the location of the SIGILL-generating bundle we'll use to handleIfDueToDyninstLib()). We construct the first here. */ /* Write the string to entry, and then move the PC to the next bundle. */ codeGen gen(BYTES_TO_SAVE); Address dyninstlib_addr = gen.used() + codeBase; gen.copy(dyninstRT_name.c_str(), dyninstRT_name.length()+1); Address dlopencall_addr = gen.used() + codeBase; /* At this point, we use the generic iRPC headers and trailers around the call to _dl_open. (Note that pre-1.35 versions of this file had a simpler mechanism well-suited to boot- strapping a new port. The current complexity is to handle the attach() case, where we don't know if execution was stopped at the entry the entry point to a function. */ bool ok = theRpcMgr->emitInferiorRPCheader(gen); if( ! ok ) { return false; } /* Generate the call to _dl_open with a large dummy constant as the the third argument to make sure we generate the same size code the second time around, with the correct "return address." (dyninstlib_brk_addr) */ // As a quick note, we want to "return" to the beginning of the restore // segment, not dyninstlib_brk_addr (or we skip all the restores). // Of course, we're not sure what this addr represents.... pdvector< AstNode * > dlOpenArguments( 4 ); AstNode * dlOpenCall; dlOpenArguments[ 0 ] = new AstNode( AstNode::Constant, (void *)dyninstlib_addr ); dlOpenArguments[ 1 ] = new AstNode( AstNode::Constant, (void *)DLOPEN_MODE ); dlOpenArguments[ 2 ] = new AstNode( AstNode::Constant, (void *)0xFFFFFFFFFFFFFFFF ); if( useFourArguments ) { /* I derived the -2 as follows: from dlfcn/dlopen.c in the glibc sources, line 59, we find the call to _dl_open(), whose last argument is 'args->file == NULL ? LM_ID_BASE : NS'. Since the filename we pass in is non-null, this means we (would) pass in NS, which is defined to be __LM_ID_CALLER in the same file, line 48. (Since glibc must be shared for us to be calling _dl_open(), we fall into the second case of the #ifdef.) __LM_ID_CALLER is defined in include/dlfcn.h, where it has the value -2. */ dlOpenArguments[ 3 ] = new AstNode( AstNode::Constant, (void *)(long unsigned int)-2 ); } dlOpenCall = new AstNode( "_dl_open", dlOpenArguments ); /* Remember where we originally generated the call. */ codeBufIndex_t index = gen.getIndex(); /* emitInferiorRPCheader() configures (the global) registerSpace for us. */ dlOpenCall->generateCode( this, regSpace, gen, true, true ); // Okay, we're done with the generation, and we know where we'll be. // Go back and regenerate it Address dlopenRet = codeBase + gen.used(); gen.setIndex(index); /* Clean up the reference counts before regenerating. */ removeAst( dlOpenCall ); removeAst( dlOpenArguments[ 2 ] ); dlOpenArguments[ 2 ] = new AstNode( AstNode::Constant, (void *)dlopenRet ); dlOpenCall = new AstNode( "_dl_open", dlOpenArguments ); /* Regenerate the call at the same original location with the correct constants. */ dlOpenCall->generateCode( this, regSpace, gen, true, true ); /* Clean up the reference counting. */ removeAst( dlOpenCall ); removeAst( dlOpenArguments[ 0 ] ); removeAst( dlOpenArguments[ 1 ] ); removeAst( dlOpenArguments[ 2 ] ); if( useFourArguments ) { removeAst( dlOpenArguments[ 3 ] ); } // Okay, that was fun. Now restore. And trap. And stuff. unsigned breakOffset, resultOffset, justAfterResultOffset; ok = theRpcMgr->emitInferiorRPCtrailer(gen, breakOffset, false, resultOffset, justAfterResultOffset ); if( ! ok ) { return false; } /* Let everyone else know that we're expecting a SIGILL. */ dyninstlib_brk_addr = codeBase + breakOffset; assert(gen.used() < BYTES_TO_SAVE); /* Save the function we're going to hijack. */ InsnAddr iAddr = InsnAddr::generateFromAlignedDataAddress( codeBase, this ); /* We need to save the whole buffer, because we don't know how big gen is when we do the restore. This could be made more efficient by storing gen.used() somewhere. */ iAddr.saveBundlesTo( savedCodeBuffer, sizeof( savedCodeBuffer ) / 16 ); /* Write the call into the mutatee. */ InsnAddr jAddr = InsnAddr::generateFromAlignedDataAddress( codeBase, this ); jAddr.writeBundlesFrom( (unsigned char *)gen.start_ptr(), gen.used() / 16 ); /* Now that we know where the code will start, move the (main thread's) PC there. */ getRepresentativeLWP()->changePC( dlopencall_addr, NULL ); /* Let them know we're working on it. */ setBootstrapState( loadingRT_bs ); return true; } /* end dlopenDYNINSTlib() */
/*Handle Server Response Function Variable Definition: -- widget: window widget -- client_socket: socket connected to the server Return value: if handle server response successful return true, else return false */ bool handleServerResponse(GtkWidget *widget, int client_socket){ RTSP_HEADER *header; //_rtsp_header structure header pointer FILE *channel; //file stream for client socket char response_line[STRING_SIZE]; //server response line char version[STRING_SIZE]; //rtsp version field: RTSP/1.0 char status_code[NUMBER_SIZE]; //rtsp response status code char status_message[STRING_SIZE]; //rtsp response status message char field_value[HALFBUF_SIZE]; //field value string char *content; //rtsp response content char *p; //string pointer int count; //counter //Initialize response_line, version, status_code, status_message, and field_value buffer memset(response_line, 0, STRING_SIZE); memset(version, 0, STRING_SIZE); memset(status_code, 0, NUMBER_SIZE); memset(status_message, 0, STRING_SIZE); memset(field_value, 0, HALFBUF_SIZE); //Create an input stream from the socket channel = fdopen(client_socket, "r"); if (channel == NULL){ showErrorCallback(widget, "fdopen() failed: unable to create received channel!"); return false; } //Get server Response Line if (fgets(response_line, STRING_SIZE, channel) == NULL){ showErrorCallback(widget, "recv() failed: unable to receive RTSP Response Line!"); return false; } //Output the client_socket id and Response Line printf("Got a call on %d: response = %s", client_socket, response_line); //Get server Header Lines header = getHeaderLines(channel); #ifdef DEBUG RTSP_HEADER *debug_header_node; DEBUG_START; fputs("RTSP response header lines:\n", stdout); //Output the RTSP response header lines for (debug_header_node = header->next; debug_header_node != NULL; debug_header_node = debug_header_node->next){ fputs(debug_header_node->field_name, stdout); fputs(": ", stdout); fputs(debug_header_node->field_value, stdout); fputc('\n', stdout); } DEBUG_END; #endif //Get server response content content = getResponseContents(channel); #ifdef DEBUG DEBUG_START; fputs("RTSP response content:\n", stdout); fputs(content, stdout); DEBUG_END; #endif //Get the rtsp version, status code, and status message sscanf(response_line, "%s%s%s", version, status_code, status_message); //Test the status code is neither 200 (OK) nor 304 (Not Modified) if ((strcmp(status_code, "200") != 0) && (strcmp(status_code, "304") != 0)){ showErrorCallback(widget, content); return false; } //Test the session field if (fieldExist(header, "session", field_value)){ //Set the session id session_id = atoi(field_value); } //Test the transport field if (fieldExist(header, "transport", field_value)){ //Remove the protocol type, protocol method, client port, and server port for (count = 0; count < NUMBER_SIZE; count++){ p = splitNameAndValue(field_value, ';'); } //Get the server rtp port number splitNameAndValue(p, '='); //Set the server rtp port number server_rtp_port = atoi(p); } //Close file stream fclose(channel); return true; }
bool handleServerResponse(GtkWidget *widget, int client_socket) { RTSP_HEADER *header; FILE *channel; char response_line[STRING_SIZE]; char version[STRING_SIZE]; char status_code[NUMBER_SIZE]; char status_message[STRING_SIZE]; char field_value[HALFBUF_SIZE]; char *content; char *p; int count; //initialize all the strings to be empty memset(response_line, 0, STRING_SIZE); memset(version, 0, STRING_SIZE); memset(status_code, 0, NUMBER_SIZE); memset(status_message, 0, STRING_SIZE); memset(field_value, 0, HALFBUF_SIZE); //Create an input stream from the socket channel = fdopen(client_socket, "r"); if (channel == NULL) { showErrorCallback(widget, "Unable to create received channel!"); return false; } //Get server Response Line if (fgets(response_line, STRING_SIZE, channel) == NULL) { showErrorCallback(widget, "Unable to receive RTSP Response!"); return false; } //Output the client_socket id and Response Line printf("Call on %d: response = %s", client_socket, response_line); //Get server Header Lines header = getHeaderLines(channel); //Get server response content content = getResponseContents(channel); //Get the rtsp version, status code, and status message sscanf(response_line, "%s%s%s", version, status_code, status_message); //Test the status code is neither 200 (OK) nor 304 (Not Modified) if ((strcmp(status_code, "200") != 0) && (strcmp(status_code, "304") != 0)) { showErrorCallback(widget, content); return false; } //Test the session field if (fieldExist(header, "session", field_value)) { //Set the session id session_id = atoi(field_value); } //Test the transport field if (fieldExist(header, "transport", field_value)) { //Remove the protocol type, protocol method, client port, and server port for (count = 0; count < NUMBER_SIZE; count++) { p = splitNameAndValue(field_value, ';'); } //Get the server rtp port number splitNameAndValue(p, '='); //Set the server rtp port number server_rtp_port = atoi(p); } //Close file stream fclose(channel); return true; }
/* * BPatch_image::findVariable * * Returns a BPatch_variableExpr* representing the given variable in the * application image. If no such variable exists, returns NULL. * * name The name of the variable to look up. * * First look for the name with an `_' prepended to it, and if that is not * found try the original name. */ BPatch_variableExpr *BPatch_image::findVariableInt(const char *name, bool showError) { pdvector<int_variable *> vars; process *llproc = proc->llproc; if (!llproc->findVarsByAll(name, vars)) { // _name? pdstring under_name = pdstring("_") + pdstring(name); if (!llproc->findVarsByAll(under_name, vars)) { // "default Namespace prefix? if (defaultNamespacePrefix) { pdstring prefix_name = pdstring(defaultNamespacePrefix) + pdstring(".") + pdstring(name); if (!llproc->findVarsByAll(prefix_name, vars)) { if (showError) { pdstring msg = pdstring("Unable to find variable: ") + pdstring(prefix_name); showErrorCallback(100, msg); } return NULL; } } else { if (showError) { pdstring msg = pdstring("Unable to find variable: ") + pdstring(name); showErrorCallback(100, msg); } return NULL; } } } assert(vars.size()); if (vars.size() > 1) { cerr << "Warning: found multiple matches for var " << name << endl; } int_variable *var = vars[0]; BPatch_variableExpr *bpvar = AddrToVarExpr->hash[var->getAddress()]; if (bpvar) { return bpvar; } // XXX - should this stuff really be by image ??? jkh 3/19/99 BPatch_Vector<BPatch_module *> *mods = getModules(); BPatch_type *type = NULL; // XXX look up the type off of the int_variable's module BPatch_module *module = NULL; for (unsigned int m = 0; m < mods->size(); m++) { if( (*mods)[m]->lowlevel_mod() == var->mod() ) { module = (*mods)[m]; break; } } if(module) { type = module->getModuleTypes()->findVariableType(name); } else { bperr("findVariable: failed look up module %s\n", var->mod()->fileName().c_str()); } if(!type) { // if we can't find the type in the module, check the other modules // (fixes prob on alpha) -- actually seems like most missing types // end up in DEFAULT_MODULE for (unsigned int m = 0; m < mods->size(); m++) { BPatch_module *tm = (*mods)[m]; type = tm->getModuleTypes()->findVariableType(name); if (type) { #if 0 char buf1[1024], buf2[1024]; tm->getName(buf1, 1024); module->getName(buf2, 1024); fprintf(stderr, "%s[%d]: found type for %s in module %s, not %s\n", FILE__, __LINE__, name, buf2, buf1); #endif break; } } if (!type) { char buf[128]; sprintf(buf, "%s[%d]: cannot find type for var %s\n", FILE__, __LINE__, name); BPatch_reportError(BPatchWarning, 0, buf); type = BPatch::bpatch->type_Untyped; } } char *nameCopy = strdup(name); assert(nameCopy); BPatch_variableExpr *ret = new BPatch_variableExpr((char *) nameCopy, proc, (void *)var->getAddress(), type); AddrToVarExpr->hash[var->getAddress()] = ret; return ret; }