/************************************************************************* * * Parse_Proc_Decl() - The "proc" declaration keyword has just * been parsed. Create Proc structure and add name to symbol table. * Get parameter LVALUES and add them to proc's local symbol table. * Get the block of text that makes up the procedure body and save * a pointer to it in the Proc struct. * ************************************************************************/ void Parse_Proc_Decl(int type) { Proc *proc; if(Get_Token() != TK_STRING) Err_Unknown(type, "identifier", NULL); /* Allocate and initialize a Proc struct... */ proc = New_User_Proc(); /* Enter proc's name in symbol table. */ Add_Symbol(token_buffer, proc, DECL_PROC); cur_proc = proc; Push_Local_Symbols(); proc_nest_level++; /* Get parameter declarations... */ Compile_Proc_Params_Decl(proc); /* Get body... */ proc->block = Parse_Block("proc"); Pop_Local_Symbols(); proc_nest_level--; cur_proc = NULL; } /* end of Parse_Proc_Decl() */
void PE_Debug::DumpSymbolInfo(std::ostream& dumpBuffer, DWORD relativeAddress ) { // Variables to keep track of function symbols PIMAGE_SYMBOL currentSym = COFFSymbolTable ; PIMAGE_SYMBOL fnSymbol = NULL ; DWORD maxFnAddress = 0 ; #ifdef DUMPRAM InitSymbols(); #endif // Variables to keep track of file symbols PIMAGE_SYMBOL fileSymbol = NULL ; PIMAGE_SYMBOL latestFileSymbol = NULL ; for ( int i = 0; i < COFFSymbolCount; i++ ) { // Look for .text section where relativeAddress belongs to. // Keep track of the filename the .text section belongs to. if ( currentSym->StorageClass == IMAGE_SYM_CLASS_FILE ) { latestFileSymbol = currentSym; } // Borland uses "CODE" instead of the standard ".text" entry // Microsoft uses sections that only _begin_ with .text const char* symName = GetSymbolName( currentSym ) ; if ( strnicmp( symName, ".text", 5 ) == 0 || strcmpi( symName, "CODE" ) == 0 ) { if ( currentSym->Value <= relativeAddress ) { PIMAGE_AUX_SYMBOL auxSym = (PIMAGE_AUX_SYMBOL)(currentSym + 1) ; if ( currentSym->Value + auxSym->Section.Length >= relativeAddress ) { fileSymbol = latestFileSymbol ; } } } // Look for the function with biggest address <= relativeAddress BOOL isFunction = ISFCN( currentSym->Type ); // Type == 0x20, See WINNT.H if ( isFunction && ( currentSym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL || currentSym->StorageClass == IMAGE_SYM_CLASS_STATIC ) ) { if ( currentSym->Value <= relativeAddress && currentSym->Value > maxFnAddress ) { maxFnAddress = currentSym->Value ; fnSymbol = currentSym ; } } #ifdef DUMPRAM if ( !isFunction && (currentSym->SectionNumber >= 0) ) { if ( (symName[0]=='_' && symName[1]!='$') || (symName[0]=='?') ) { char pretty_module[1024]; if ( fileSymbol ) { const char* auxSym = (const char*)(latestFileSymbol + 1) ; char tmpFile[ VA_MAX_FILENAME_LEN ] ; strcpy_s( tmpFile, auxSym ) ; strcpy_s( pretty_module, tmpFile ); char *p = pretty_module+strlen(pretty_module)-1; // Move p to point to first letter of EXE filename while( (*p!='\\') && (*p!='/') && (*p!=':') ) p--; p++; if ( strlen(p) < 1 ) { strcpy_s( pretty_module, "<unknown>" ); } else { memmove( pretty_module, p, strlen(p)+1 ); } } else { strcpy_s( pretty_module, "" ); } Add_Symbol( currentSym->SectionNumber, currentSym->Value, symName, pretty_module ); } } #endif // Advance counters, skip aux symbols i += currentSym->NumberOfAuxSymbols ; currentSym += currentSym->NumberOfAuxSymbols ; currentSym++ ; } #ifdef DUMPRAM DumpSymbols(); #endif // dump symbolic info if found if ( fileSymbol ) { const char* auxSym = (const char*)(fileSymbol + 1) ; if( strcmpi( latestFile, auxSym ) ) { strcpy_s( latestFile, auxSym ) ; //JAS dumpBuffer.Printf( " file: %s\r\n", auxSym ) ; } } else { latestFile[ 0 ] = 0 ; //JAS dumpBuffer.Printf( " file: unknown\r\n" ) ; } if ( fnSymbol ) { char tmp_name[1024]; unmangle(tmp_name, GetSymbolName( fnSymbol ) ); dumpBuffer << " " << tmp_name << "()"; } else { dumpBuffer << " <unknown>"; } }
/************************************************************************* * * Parse_Local_Decl() - Process user defined types and declarations * that are local to the body of a user-defined procedure. * Assumes that a non-keyword identifier name has just been parsed * and the global, "token_buffer", contains the name. If * initialization expressions are processed, a STATEMENT list will * be constructed and returned. * ************************************************************************/ STATEMENT *Parse_Local_Decl(Proc *proc, int type, const char *block_name) { int token; STATEMENT *stmt = NULL, *s = NULL; EXPR *expr; static char name[MAX_TOKEN_BUF_SIZE]; assert(proc != NULL); local_only = 1; if((token = Get_Token()) != TK_STRING) Err_Unknown(token, "identifier", block_name); local_only = 0; if(scn_error_cnt) return NULL; strcpy(name, token_buffer); switch(type) { case TK_FLOAT: case TK_VECTOR: { LVALUE *lv; while(1) { /* Initialize l-value data structure... */ lv = New_Lvalue(type); /* If there is an initializer expr? */ if((expr = Compile_Lvalue_Expr(lv)) != NULL) { if(s != NULL) { s->next = New_Statement(TK_PROC_EXPR); s = s->next; } else s = stmt = New_Statement(TK_PROC_EXPR); s->exec = Exec_Expr; s->expr = expr; } /* Add new l-value to dictionary and proc... */ Add_Symbol(name, (void *)lv, DECL_LVALUE); Proc_Add_Local(proc, lv); if(Get_Token() != OP_COMMA) { Unget_Token(); break; /* Done, break from loop. */ } /* * Gotta comma. Get next name, and recycle... */ local_only = 1; if((token = Get_Token()) != TK_STRING) Err_Unknown(token, "identifier", block_name); local_only = 0; strcpy(name, token_buffer); } /* end of comma loop */ } break; default: SCN_Message(SCN_MSG_ERROR, "%s: Invalid declaration type.", block_name); break; } /* end of "type" switch */ return stmt; } /* end of Parse_Local_Decl() */