// Pre: disambig_fp has been initialized and disambig_writing is True
void generateDisambigFile() {
  FuncIterator* funcIt;
  TypeIterator* typeIt;

  // Write entries for global variables:
  fputs(ENTRY_DELIMETER, disambig_fp);
  fputs("\n", disambig_fp);
  fputs(GLOBAL_STRING, disambig_fp);
  fputs("\n", disambig_fp);

  visitVariableGroup(GLOBAL_VAR,
                     0,
                     0,
                     0,
		     0,
                     &printDisambigAction);

  fputs("\n", disambig_fp);

  // Write entries for function parameters and return values:
  funcIt = newFuncIterator();

  while (hasNextFunc(funcIt)) {
    FunctionEntry* cur_entry = nextFunc(funcIt);

    tl_assert(cur_entry);

    // Only write .disambig entries for program points that are listed
    // in prog-pts-file, if we are using the --prog-pts-file option:
    if (!fjalar_trace_prog_pts_filename ||
        // If fjalar_trace_prog_pts_filename is on (we are reading in
        // a ppt list file), then DO NOT OUTPUT entries for program
        // points that we are not interested in.
        prog_pts_tree_entry_found(cur_entry)) {
      fputs(ENTRY_DELIMETER, disambig_fp);
      fputs("\n", disambig_fp);
      fputs(FUNCTION_PREFIX, disambig_fp);
      fputs(cur_entry->fjalar_name, disambig_fp);
      fputs("\n", disambig_fp);

      // Print out all function parameter return value variable names:
      visitVariableGroup(FUNCTION_FORMAL_PARAM,
                         cur_entry,
                         0,
                         0,
			 0,
                         &printDisambigAction);

      visitVariableGroup(FUNCTION_RETURN_VAR,
                         cur_entry,
                         0,
                         0,
			 0,
                         &printDisambigAction);

      fputs("\n", disambig_fp);
    }
  }
  deleteFuncIterator(funcIt);

  // Write entries for every struct/class in TypesTable, with the
  // type's name prefixed by 'usertype.':
  typeIt = newTypeIterator();

  while (hasNextType(typeIt)) {
    TypeEntry* cur_entry = nextType(typeIt);

    tl_assert(cur_entry && cur_entry->typeName);

    fputs(ENTRY_DELIMETER, disambig_fp);
    fputs("\n", disambig_fp);
    fputs(USERTYPE_PREFIX, disambig_fp);
    fputs(cur_entry->typeName, disambig_fp);
    fputs("\n", disambig_fp);

    visitClassMembersNoValues(cur_entry,
                              &printDisambigAction);

    fputs("\n", disambig_fp);
  }

  deleteTypeIterator(typeIt);
}
Example #2
0
// This inserts an IR Statement responsible for calling func
// code before the instruction at addr is executed. This is primarily
// used for inserting the call to enter_function on function entry.
// It is also used for handling of 'function priming' for GCC 3 (see
// comment above prime_function). The result of looking up addr in
// table will be passed to func as it's only argument. This function
// does nothing if it is unable to successfully look up addr in the
// provided table.
static void handle_possible_entry_func(MCEnv *mce, Addr64 addr,
				       struct genhashtable *table,
				       const char *func_name,
				       entry_func func) {
  IRDirty  *di;
  FunctionEntry *entry = gengettable(table, (void *)(Addr)addr);

  if(!entry) {
      return;
  }

  // If fjalar_trace_prog_pts_filename is on (we are using a ppt list
  // file), then DO NOT generate IR code to call helper functions for
  // functions whose name is NOT located in prog_pts_tree. It's faster
  // to filter them out at translation-time instead of run-time
  if (entry && (!fjalar_trace_prog_pts_filename ||
		prog_pts_tree_entry_found(entry))) {
    UWord entry_w = (UWord)entry;
    di = unsafeIRDirty_0_N(1/*regparms*/, func_name, func,
			 mkIRExprVec_1(IRExpr_Const(IRConst_UWord(entry_w))));

    // For function entry, we are interested in observing the stack
    // and frame pointers so make sure that they're updated by setting
    // the proper annotations:

    entry->entryPC = addr;

    FJALAR_DPRINTF("Found a valid entry point at %x for\n", (UInt)addr);

    // We need all general purpose registers.
    di->nFxState = 9;
    vex_bzero(&di->fxState, sizeof(di->fxState));

    di->fxState[0].fx     = Ifx_Read;
    di->fxState[0].offset = mce->layout->offset_SP;
    di->fxState[0].size   = mce->layout->sizeof_SP;
    di->fxState[1].fx     = Ifx_Read;
    di->fxState[1].offset = mce->layout->offset_FP;
    di->fxState[1].size   = mce->layout->sizeof_FP;
    di->fxState[2].fx     = Ifx_Read;
    di->fxState[2].offset = mce->layout->offset_IP;
    di->fxState[2].size   = mce->layout->sizeof_IP;

    di->fxState[3].fx     = Ifx_Read;
    di->fxState[3].offset = mce->layout->offset_xAX;
    di->fxState[3].size   = mce->layout->sizeof_xAX;
    di->fxState[4].fx     = Ifx_Read;
    di->fxState[4].offset = mce->layout->offset_xBX;
    di->fxState[4].size   = mce->layout->sizeof_xBX;
    di->fxState[5].fx     = Ifx_Read;
    di->fxState[5].offset = mce->layout->offset_xCX;
    di->fxState[5].size   = mce->layout->sizeof_xCX;

    di->fxState[6].fx     = Ifx_Read;
    di->fxState[6].offset = mce->layout->offset_xDX;
    di->fxState[6].size   = mce->layout->sizeof_xDX;
    di->fxState[7].fx     = Ifx_Read;
    di->fxState[7].offset = mce->layout->offset_xSI;
    di->fxState[7].size   = mce->layout->sizeof_xSI;
    di->fxState[8].fx     = Ifx_Read;
    di->fxState[8].offset = mce->layout->offset_xDI;
    di->fxState[8].size   = mce->layout->sizeof_xDI;

    stmt('V',  mce, IRStmt_Dirty(di) );
  }
}
Example #3
0
// Handle a function exit statement, which contains a jump kind of
// 'Ret'.  It seems pretty accurate to cue off of currentAddr, a value
// that is updated every time an Ist_IMark statement is translated,
// which is quite often
void handle_possible_exit(MCEnv* mce, IRJumpKind jk) {
  if (Ijk_Ret == jk) {
    IRDirty  *di;

    FunctionEntry* curFuncPtr = getFunctionEntryFromAddr(currentAddr);

    if (curFuncPtr &&
	// Also, if fjalar_trace_prog_pts_filename is on (we are
	// reading in a ppt list file), then DO NOT generate IR code
	// to call helper functions for functions whose names are NOT
	// located in prog_pts_tree.  This will greatly speed up
	// processing because these functions are filtered out at
	// translation-time, not at run-time
	(!fjalar_trace_prog_pts_filename ||
	 prog_pts_tree_entry_found(curFuncPtr))) {

      FJALAR_DPRINTF("[handle_possible_exit] %s - %x\n", curFuncPtr->fjalar_name, (UInt)currentAddr);

      // The only argument to exit_function() is a pointer to the
      // FunctionEntry for the function that we are exiting
      di = unsafeIRDirty_0_N(1/*regparms*/,
			     "exit_function",
			     &exit_function,
			     mkIRExprVec_1(IRExpr_Const(IRConst_UWord((Addr)curFuncPtr))));

      // For function exit, we are interested in observing  all general purpose
      // integer registers,  FTOP, and FPREG[], so make sure that they are
      // updated by setting the proper annotations.
      di->nFxState = 11;
      vex_bzero(&di->fxState, sizeof(di->fxState));

      di->fxState[0].fx     = Ifx_Read;
      di->fxState[0].offset = mce->layout->offset_SP;
      di->fxState[0].size   = mce->layout->sizeof_SP;
      di->fxState[1].fx     = Ifx_Read;
      di->fxState[1].offset = mce->layout->offset_FP;
      di->fxState[1].size   = mce->layout->sizeof_FP;
      di->fxState[2].fx     = Ifx_Read;
      di->fxState[2].offset = mce->layout->offset_IP;
      di->fxState[2].size   = mce->layout->sizeof_IP;

      di->fxState[3].fx     = Ifx_Read;
      di->fxState[3].offset = mce->layout->offset_xAX;
      di->fxState[3].size   = mce->layout->sizeof_xAX;
      di->fxState[4].fx     = Ifx_Read;
      di->fxState[4].offset = mce->layout->offset_xBX;
      di->fxState[4].size   = mce->layout->sizeof_xBX;
      di->fxState[5].fx     = Ifx_Read;
      di->fxState[5].offset = mce->layout->offset_xCX;
      di->fxState[5].size   = mce->layout->sizeof_xCX;

      di->fxState[6].fx     = Ifx_Read;
      di->fxState[6].offset = mce->layout->offset_xDX;
      di->fxState[6].size   = mce->layout->sizeof_xDX;
      di->fxState[7].fx     = Ifx_Read;
      di->fxState[7].offset = mce->layout->offset_xSI;
      di->fxState[7].size   = mce->layout->sizeof_xSI;
      di->fxState[8].fx     = Ifx_Read;
      di->fxState[8].offset = mce->layout->offset_xDI;
      di->fxState[8].size   = mce->layout->sizeof_xDI;

      di->fxState[9].fx     = Ifx_Read;
      di->fxState[9].offset = offsetof(VexGuestArchState, guest_FTOP);
      di->fxState[9].size   = sizeof(UInt); /* FTOP is 4 bytes even on x64 */
      di->fxState[10].fx     = Ifx_Read;
      di->fxState[10].offset = offsetof(VexGuestArchState, guest_FPREG);
      di->fxState[10].size   = 8 * sizeof(ULong);

      stmt('V',  mce, IRStmt_Dirty(di) );
    }
  }
}
/*
----SECTION----
globals

----SECTION----
..main()
return

----SECTION----
Stack.cpp.Stack::getNumStacksCreated()
return

----SECTION----
Stack.cpp.Stack::Link::initialize(char*, Stack::Link*)
this
this->data
this->data[]
this->next
this->next[].data
this->next[].data[0]
*/
void outputVariableNamesToFile() {
  FuncIterator* funcIt;
  g_open_fp = var_dump_fp;

  // Print out a section for all global variables:
  fputs(ENTRY_DELIMETER, var_dump_fp);
  fputs("\n", var_dump_fp);
  fputs(GLOBAL_STRING, var_dump_fp);
  fputs("\n", var_dump_fp);

  visitVariableGroup(GLOBAL_VAR,
                     0,
                     0,
                     0,
		     0,
                     &printVarNameAction);

  fputs("\n", var_dump_fp);

  funcIt = newFuncIterator();

  // Print out a section for all relevant functions:
  while (hasNextFunc(funcIt)) {
    FunctionEntry* cur_entry = nextFunc(funcIt);

    tl_assert(cur_entry);

    // Only dump variable entries for program points that are listed
    // in prog-pts-file, if we are using the --prog-pts-file option:
    if (!fjalar_trace_prog_pts_filename ||
        // If fjalar_trace_prog_pts_filename is on (we are reading in
        // a ppt list file), then DO NOT OUTPUT entries for program
        // points that we are not interested in.
        prog_pts_tree_entry_found(cur_entry)) {
      fputs(ENTRY_DELIMETER, var_dump_fp);
      fputs("\n", var_dump_fp);
      fputs(cur_entry->fjalar_name, var_dump_fp);
      fputs("\n", var_dump_fp);

      // Print out all function parameter return value variable names:
      visitVariableGroup(FUNCTION_FORMAL_PARAM,
                         cur_entry,
                         0,
                         0,
			 0,
                         &printVarNameAction);

      visitVariableGroup(FUNCTION_RETURN_VAR,
                         cur_entry,
                         0,
                         0,
			 0,
                         &printVarNameAction);

      fputs("\n", var_dump_fp);
    }
  }
  deleteFuncIterator(funcIt);

  g_open_fp = 0;
}