예제 #1
0
int Syscall::kcall_threadcreate(CoreData& core_data, Thread *currt) {

    /*
     * Create a new thread the POSIX way
     *
     * KPARM1 : attr
     * KPARM2 : start_routine
     * KPARM3 : arg
     *
     * retval : tid or -ERRNO
     */

    //Thread       *org_thread;
    pthread_attr_t      attr;
    int                 err;
    mm_context   *ctx;
    Process             *pproc;
//    struct _Anvil_tls   *ptls;

    kdebug("kcall_threadcreate %016lx\n", KPARM2);

    /* Validate the args */
    if ((err = currt->kcopy_fromuser(&attr, (const char *)KPARM1,
                                        sizeof(pthread_attr_t))) != 0) {
        kdebug("kcall_threadcreate - bad attr structure\n");
        return -err;
    }

    if (currt->ptr_check((void *)KPARM2) == -1) {
        kdebug("kcall_threadcreate - bad start routine\n");
        return -EINVAL;
    }

    /* Handle the case of someone creating thread 1 in a new process */
    if (attr.pid) {
        if ((pproc = proctable.getref(attr.pid)) == NULL)
        {
            return -EAGAIN;
        }
    }
    else
    {
        pproc = currt->get_proc();
        pproc->incref();
    }

    /*
     * FIXME: It should be possible to do this a different way
     * Get the cr3 of the process we'll be creating in
     */
    ctx = pproc->ctx;

    /*
     * According to Posix the user may pass us both stacksize and stackaddr,
     * just stacksize or nothing. If the user passes nothing we use the
     * default (4 * __PAGESIZE).
     */
    if (attr.stackaddr) {
        /* The user passed us a stack - make sure that he gave us the size
         * as well and check it
         */
        if (!attr.stacksize) {
            return -EINVAL;
        }
        /* Check */
    }
    if (!attr.stacksize) {
        attr.stacksize = 4 * __PAGESIZE;
    }

    void *stk;
    size_t stk_size;

    /* Now check whether we need to create a stack. */
    if (attr.stackaddr) {
        kdebug("Passing in stack %016lx\n", attr.stackaddr);
        /* We already checked that the address and size are valid */
        stk = (char *)attr.stackaddr;
        stk_size = attr.stacksize;
    }
    else {
        kdebug("Creating stack\n");
        //ksched_block(THR_ST_CREATING);
        int err = mm_mmap(pproc->ctx, 0, attr.stacksize,
                PROT_READ|PROT_WRITE, MAP_ANON|MAP_GUARD,
                -1, 0, &stk);
        stk_size = attr.stacksize;
        //kdebug("Created stack %d %d %p %ld\n", tnew->get_pid(), tnew->get_id(), tnew->stackaddr, tnew->stacksize);
    }

    /* Seems okay so let's create a new thread */
    Thread *tnew = new Thread(KPARM2, KPARM3, stk, stk_size);

    if ((err = pproc->thread_add(tnew)) != 0)
    {
        kprintf("kcall_threadcreate (kobj_create) - err %d\n", -err);
        pproc->unref();
        return -err;
    }

    /* Initialise the thread context */
    if (attr.stopped)
    {
        tnew->set_state(THR_ST_STOPPED);
    }

    /* Some fields are inherited from the creating thread */
    tnew->priority     = currt->priority;
    tnew->m_thread_signal.set_blocked(currt->m_thread_signal.get_blocked());
    tnew->max_addr     = currt->max_addr;
    tnew->ctx          = ctx;

    tnew->init_tls(attr.return_func);

    /* Unblock the new thread - sets the state to THR_ST_READY */
    if (tnew->get_state() == THR_ST_READY) {
        sys.m_sched.add(tnew, 0);
    }

    tnew->activate();
    //kobj_unlock(KOBJ(tnew));

    kdebug("finished STARTING1 %d %d thread at %016lx\n", tnew->get_pid(), tnew->get_id(), tnew->reg.rip);

    //pproc->unref();

    return tnew->get_id();
}
예제 #2
0
파일: SBFrame.cpp 프로젝트: filcab/lldb
SBValue
SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic)
{
    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    SBValue sb_value;
    
    if (name == NULL || name[0] == '\0')
    {
        if (log)
            log->Printf ("SBFrame::FindValue called with empty name.");
        return sb_value;
    }
    
    ValueObjectSP value_sp;
    Mutex::Locker api_locker;
    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);

    StackFrame *frame = NULL;
    Target *target = exe_ctx.GetTargetPtr();
    Process *process = exe_ctx.GetProcessPtr();
    if (target && process)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process->GetRunLock()))
        {
            frame = exe_ctx.GetFramePtr();
            if (frame)
            {
                switch (value_type)
                {
                case eValueTypeVariableGlobal:      // global variable
                case eValueTypeVariableStatic:      // static variable
                case eValueTypeVariableArgument:    // function argument variables
                case eValueTypeVariableLocal:       // function local variables
                    {
                        VariableList *variable_list = frame->GetVariableList(true);

                        SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock));

                        const bool can_create = true;
                        const bool get_parent_variables = true;
                        const bool stop_if_block_is_inlined_function = true;

                        if (sc.block && sc.block->AppendVariables (can_create, 
                                                                   get_parent_variables,
                                                                   stop_if_block_is_inlined_function,
                                                                   variable_list))
                        {
                            ConstString const_name(name);
                            const uint32_t num_variables = variable_list->GetSize();
                            for (uint32_t i = 0; i < num_variables; ++i)
                            {
                                VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
                                if (variable_sp && 
                                    variable_sp->GetScope() == value_type &&
                                    variable_sp->GetName() == const_name)
                                {
                                    value_sp = frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues);
                                    sb_value.SetSP (value_sp, use_dynamic);
                                    break;
                                }
                            }
                        }
                    }
                    break;

                case eValueTypeRegister:            // stack frame register value
                    {
                        RegisterContextSP reg_ctx (frame->GetRegisterContext());
                        if (reg_ctx)
                        {
                            const uint32_t num_regs = reg_ctx->GetRegisterCount();
                            for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
                            {
                                const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_idx);
                                if (reg_info && 
                                    ((reg_info->name && strcasecmp (reg_info->name, name) == 0) ||
                                     (reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0)))
                                {
                                    value_sp = ValueObjectRegister::Create (frame, reg_ctx, reg_idx);
                                    sb_value.SetSP (value_sp);
                                    break;
                                }
                            }
                        }
                    }
                    break;

                case eValueTypeRegisterSet:         // A collection of stack frame register values
                    {
                        RegisterContextSP reg_ctx (frame->GetRegisterContext());
                        if (reg_ctx)
                        {
                            const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
                            for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
                            {
                                const RegisterSet *reg_set = reg_ctx->GetRegisterSet (set_idx);
                                if (reg_set && 
                                    ((reg_set->name && strcasecmp (reg_set->name, name) == 0) ||
                                     (reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0)))
                                {
                                    value_sp = ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx);
                                    sb_value.SetSP (value_sp);
                                    break;
                                }
                            }
                        }
                    }
                    break;

                case eValueTypeConstResult:         // constant result variables
                    {
                        ConstString const_name(name);
                        ClangExpressionVariableSP expr_var_sp (target->GetPersistentVariables().GetVariable (const_name));
                        if (expr_var_sp)
                        {
                            value_sp = expr_var_sp->GetValueObject();
                            sb_value.SetSP (value_sp, use_dynamic);
                        }
                    }
                    break;

                default:
                    break;
                }
            }
            else
            {
                if (log)
                    log->Printf ("SBFrame::FindValue () => error: could not reconstruct frame object for this SBFrame.");
            }
        }
        else
        {
            if (log)
                log->Printf ("SBFrame::FindValue () => error: process is running");
        }
    }
    
    if (log)
        log->Printf ("SBFrame(%p)::FindVariableInScope (name=\"%s\", value_type=%i) => SBValue(%p)", 
                     frame, name, value_type, value_sp.get());

    
    return sb_value;
}
예제 #3
0
//Purpose: Runs the shortest job first algorithm
//Parameters: The number of processes (int numOfP)
void startSJF(int numOfP){
  std::cout << std::endl << "Starting SJF Simulation...\n" << std::endl;
  //queues for simulation
  std::priority_queue< Event, std::vector<Event>, Event::CompTime> eventQueue;//event queue for holding various events
  std::priority_queue< Process, std::vector<Process>, Process::CompDur > readyQueue;//ready queue for holding processes
  std::priority_queue< Process, std::vector<Process>, Process::CompIO > IOArray;//used for holding process that are waiting for an IO device


  std::priority_queue< Event, std::vector<Event>, Event::CompTime> tempEventQueue;
  std::priority_queue< Process, std::vector<Process>, Process::CompDur > tempProcessQueue;

  std::vector<Process> ProcessArray;//used for final output

  //Time variables
  double totalTime = 300.0;//total time executed
  double currentTime = 0.0;//Initialize current time
  double randomDouble = 0.0;//used for various things

  int currentEvent;//holds the current event type
  Process newP;//used for new processes
  Process CPUProcess;//process in the CPU
  int IDcount = 0;//for the process IDs
  bool CPUBusy = false;//flag for checking if the CPU has a process in it
  double CPUIdleTime = 0.0;//time that the CPU was not working
  double CPUIdleTimeTemp = 0.0;//assists finding CPU idle time
  

  srand(time(0));//set random seed
  Event newE;//temporary event holder
  long n = -2;//for random numbers


  for (int i = 0; i < numOfP; i++){
    newE.setEventType(1);//new event = process arrival
    randomDouble = ( rand() % 300000 );
    randomDouble = randomDouble/1000;
    newE.setTimeOfEvent(rand() % 299 + ran1(&n));
    eventQueue.push(newE);
    //std::cout << newE.getTimeOfEvent() << std::endl;
  }

  
  int tempI; //not needed
  while ((!eventQueue.empty())){

    currentEvent = eventQueue.top().getEventType();
    currentTime = eventQueue.top().getTimeOfEvent();
    eventQueue.pop();//erase front event
    switch(currentEvent){
    case 1://Process Arrival
      
      //adds to the ready queue
      randomDouble = ( rand() % 60000 );
      randomDouble = randomDouble/1000;
      newP.setTotalDuration(randomDouble);

      //average burst
      randomDouble = ( rand() % 95 ) + 5;
      newP.setAverageBurst(randomDouble);//Ϯn+1 = αᵼn + (1 - α)Ϯn


      newP.setStatus("Ready");
      newP.setProcessID(IDcount);
      newP.setArrivalTime(currentTime);
      newP.setRemainingDuration(0.0);
      newP.setIOBurst(0.0);
      newP.setIOBurstTotal(0.0);
      newP.setWaitingTime(0.0);
      newP.setLastRun(0.0);
      IDcount++;//increment ID, next ID will be the ID of current process + 1

      //set next burst
      randomDouble = CPUBurstRandom(newP.getAverageBurst());
      randomDouble = randomDouble/1000;
      if(randomDouble <= 0.0){randomDouble += 0.001;}//CPUBurstRandom() can generate 0.0 sometimes
      newP.setNextBurst(randomDouble);
      readyQueue.push(newP);//push it to the back


      //checks the CPU to see if it is busy
      if (CPUBusy){

      }
      else{//if it isnt, add the new process into the CPU
	CPUBusy = true;
	CPUIdleTime = (currentTime - CPUIdleTimeTemp) + CPUIdleTime;
	CPUProcess = readyQueue.top();
	CPUProcess.setStatus("Running");
	//std::cout << "CPUProcess: " << CPUProcess.getProcessID() <<  " Inserted" <<std::endl;
	
	readyQueue.pop();//erase front event
	newE.setEventType(2);
	newE.setTimeOfEvent(currentTime+CPUProcess.getNextBurst());
	//add the event completion time to the event queue
	//std::cout << "Event Processes at: " << newE.getTimeOfEvent() << std::endl;
	eventQueue.push(newE);
      }


      break;
      
    case 2://CPU Burst Completion
      

      //std::cout << "CPUProcess: " << CPUProcess.getProcessID() << " is done" << std::endl;
      
      CPUProcess.setRemainingDuration(CPUProcess.getRemainingDuration() + CPUProcess.getNextBurst());
      //std::cout << CPUProcess.getProcessID() << " " << CPUProcess.getTotalDuration() << " " << CPUProcess.getRemainingDuration() << std::endl;
      //check if CPU pocess is done
      if (CPUProcess.getRemainingDuration() >= CPUProcess.getTotalDuration()){
	CPUProcess.setStatus("Terminated");
	// Output its information and insert into 'finished array' 
	ProcessArray.push_back(output(CPUProcess, currentTime));
      }
      else{// Generate IO burst and insert into IO queue
	CPUProcess.setStatus("Waiting");
	CPUProcess.setLastRun(currentTime);
	randomDouble = ( rand() % 70 ) + 30;
	randomDouble = randomDouble/1000;
	CPUProcess.setIOBurst(randomDouble);
	IOArray.push(CPUProcess);
	// Generate event for when the IO time is done
	newE.setEventType(3);
	newE.setTimeOfEvent(currentTime+CPUProcess.getIOBurst());
	// Insert event into IO queue
	eventQueue.push(newE);
      }




      //Put new Process into CPU if there is no process in there
      if(!readyQueue.empty()){
	//add new process to CPU
	CPUProcess = readyQueue.top();
	CPUProcess.setStatus("Running");
	CPUProcess.setWaitingTime(CPUProcess.getWaitingTime() + (currentTime - CPUProcess.getLastRun()) );
	
	readyQueue.pop();//erase front event
	newE.setEventType(2);
	newE.setTimeOfEvent(currentTime+CPUProcess.getNextBurst());
	eventQueue.push(newE);
	//std::cout << "CPUProcess: " << CPUProcess.getProcessID() <<  " Inserted" <<std::endl;
      }
      //if no process in ready queue, set CPU flag to not busy
      else{ //set CPU to idle
	CPUBusy = false; 
	CPUIdleTimeTemp = currentTime;
	//std::cout << "CPU Idle" <<std::endl;
      }

      break;

    case 3:// I/O Completion
      
      //take the process out of the IO queue
      newP = IOArray.top();//IOArray.front();//changed
      IOArray.pop();//IOArray.erase(IOArray.begin());//changed

      //std::cout << newP.getAverageBurst() << " " << newP.getNextBurst() << std::endl;
      newP.setNewAverageBurst(newP.getNextBurst()*1000.0, 0.2);//Ϯn+1 = αᵼn + (1 - α)Ϯn
      //std::cout << newP.getAverageBurst() << std::endl;

      //reinsert the process into the readyQueue
      newP.setLastRun(currentTime);
      randomDouble = CPUBurstRandom(newP.getAverageBurst());
      randomDouble = randomDouble/1000;

      //CPUBurstRandom tends to generate numbers lower than the average for some reason
      //This is placed to make sure the bursts don't reach 0.0.
      if (randomDouble < 0.010) { randomDouble = 0.010; }
      newP.setNextBurst(randomDouble);


      newP.setStatus("Waiting");
      newP.setIOBurstTotal(newP.getIOBurst() + newP.getIOBurstTotal());
      readyQueue.push(newP);

      //check if CPU has a process
      if (CPUBusy){
	//std::cout << "CPU is Busy" << std::endl;
      }
      else{//if it isnt, add the new process into the CPU
	CPUBusy = true;
	CPUIdleTime = (currentTime - CPUIdleTimeTemp) + CPUIdleTime;
	CPUProcess = readyQueue.top();
	CPUProcess.setStatus("Running");
	CPUProcess.setWaitingTime(CPUProcess.getWaitingTime() + (currentTime - CPUProcess.getLastRun()));
	readyQueue.pop();//erase front event
	newE.setEventType(2);
	newE.setTimeOfEvent(currentTime+CPUProcess.getNextBurst());
	eventQueue.push(newE);
      }

      break;

    case 4:// Timer Expiration - Shouldnt be reached
      
      break;

    default: 
      
      break;
    }
    
  }
  finalOutput(ProcessArray, CPUIdleTime, currentTime);
}
예제 #4
0
extern int main ( int argc, char *argv[] ) {

  /**************************************************************************
   * Register self.                                                         *
   **************************************************************************/

   Sys_RegisterThread ( ) ;

  /**************************************************************************
   * Set a default exception filter.                                        *
   **************************************************************************/

   REGISTER_EXCEPTION_HANDLER(0);

  /**************************************************************************
   * Start the main block (for constructors/destructors).                   *
   **************************************************************************/

   {

  /**************************************************************************
   * Get the initial file path for loading files from command-line.         *
   **************************************************************************/

   char InitialPath [CCHMAXPATH] ;
   _fullpath ( InitialPath, ".", sizeof(InitialPath) ) ;
   strcat ( InitialPath, "\\" ) ;

  /**************************************************************************
   * Determine the home directory.                                          *
   **************************************************************************/

   char Drive [_MAX_DRIVE+1], Dir[_MAX_DIR+1], Fname[_MAX_FNAME+1], Ext[_MAX_EXT+1] ;
   strupr ( argv[0] ) ;
   _fullpath ( HomePath, argv[0], sizeof(HomePath) ) ;
   _splitpath ( HomePath, Drive, Dir, Fname, Ext ) ;
   if ( Dir[strlen(Dir)-1] == '\\' )
      Dir[strlen(Dir)-1] = 0 ;
   strcpy ( HomePath, Drive ) ;
   strcat ( HomePath, Dir ) ;

   _chdrive ( Drive[0] - 'A' + 1 ) ;
   _chdir ( "\\" ) ;
   _chdir ( Dir ) ;

  /**************************************************************************
   * Set the C RunTime Library error message file handle.                   *
   **************************************************************************/

   #ifdef __DEBUG_ALLOC__
      Log ( "Escriba::main: Program started." ) ;
      _set_crt_msg_handle ( fileno(Logfile) ) ;
   #else
      #ifdef DEBUG
         Log ( "Escriba::main: Program started." ) ;
      #endif // DEBUG
   #endif // __DEBUG_ALLOC__

  /**************************************************************************
   * Determine if another instance of this program is present.              *
   *   If so, pass the command-line information to it.                      *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Checking for another instance already loaded." ) ;
   #endif // DEBUG

   PublicMemory Memory ( MEMORY_NAME, sizeof(SHARED_MEMORY), TRUE ) ;
   if ( NOT Memory.QueryCreated() ) {

      // Get the main instance's window handle.  Wait up to 20 seconds if necessary.
      HWND MainWindow = ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow ;
      clock_t LastClock = clock ( ) ;
      while ( MainWindow == 0 ) {
         if ( ( ( clock() - LastClock ) / CLOCKS_PER_SEC ) > 20 ) {
            Log ( "ERROR: Unable to get previous instance window handle." ) ;
            return ( 1 ) ;
         } /* endif */
         DosSleep ( 100 ) ;
         MainWindow = ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow ;
      } /* endwhile */

      // If any command-line parameters were given . . .
      if ( argc > 1 ) {

         // Build a command-line string.
         char Parms [512] = { 0 } ;
         int ParmLength = 0 ;
         while ( --argc ) {
            strcpy ( Parms+ParmLength, *(++argv) ) ;
            ParmLength += strlen(*argv) + 1 ;
         } /* endwhile */
         Parms[++ParmLength] = 0 ;

         // Get the original process's ID.
         PID Process ;
         TID Thread ;
         if ( !WinQueryWindowProcess ( MainWindow, &Process, &Thread ) ) {
            char Message [512] ;
            Log ( "ERROR: Unable to query window process.  %s", InterpretWinError(0,Message) ) ;
            return ( 1 ) ;
         } /* endif */

         // Allocate shared memory to hold the current path.
         PVOID Memory1 ;
         APIRET Status = DosAllocSharedMem ( &Memory1, 0, strlen(InitialPath)+1, fALLOC | OBJ_GIVEABLE | OBJ_GETTABLE) ;
         if ( Status ) {
            Log ( "ERROR: Unable to allocate shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */
         strcpy ( PCHAR(Memory1), InitialPath ) ;

         // Allocate shared memory to hold the command-line.
         PVOID Memory2 ;
         Status = DosAllocSharedMem ( &Memory2, 0, ParmLength, fALLOC | OBJ_GIVEABLE | OBJ_GETTABLE) ;
         if ( Status ) {
            Log ( "ERROR: Unable to allocate shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */
         memcpy ( Memory2, Parms, ParmLength ) ;

         // Make both shared memory blocks available to the original process.
         Status = DosGiveSharedMem ( Memory1, Process, PAG_READ | PAG_WRITE ) ;
         DosFreeMem ( Memory1 ) ;
         if ( Status ) {
            Log ( "ERROR: Unable to give shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */
         Status = DosGiveSharedMem ( Memory2, Process, PAG_READ | PAG_WRITE ) ;
         DosFreeMem ( Memory2 ) ;
         if ( Status ) {
            Log ( "ERROR: Unable to give shared memory.  Status %d.", Status ) ;
            return ( 1 ) ;
         } /* endif */

         // Pass the information to the original process.
         Sys_PostMessage ( MainWindow, WM_LOAD_FILE, MPFROMP(Memory1), MPFROMP(Memory2) ) ;

      } /* endif */

      // Bring the previous instance to the fore.
      Sys_SetActiveWindow ( MainWindow ) ;

      // We're outta here . . .
      return ( 0 ) ;

   } /* endif */

  /**************************************************************************
   * If the ISPELL environment variable isn't set, set it to the current    *
   *   directory, before we change it.  This assumes that the current       *
   *   directory is also the directory to which Escriba (and ISPELL) was    *
   *   installed.  This is true with the basic installation.                *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Setting ISPELL environment variable." ) ;
   #endif // DEBUG

   {
      char *p = getenv ( "ISPELL" ) ;
      if ( p == 0 ) {
         static char SetString [_MAX_PATH+10] ;
         sprintf ( SetString, "ISPELL=%s", HomePath ) ;
         _putenv ( SetString ) ;
      } /* endif */
   }

  /**************************************************************************
   * Get application language module.                                       *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Loading default language." ) ;
   #endif // DEBUG

   char DefaultLanguage [80] = { 0 } ;

   { /* startblock */
      Profile IniFile ( PSZ(PROGRAM_NAME), 0, HomePath ) ;
      if ( IniFile.QueryHandle() ) 
         IniFile.GetString ( "Language", DefaultLanguage, sizeof(DefaultLanguage) ) ;
      else
         strcpy ( DefaultLanguage, "English" ) ;
   } /* endblock */

   Library = Language_Create ( PROGRAM_NAME, REVISION, IDS_TITLE1, DefaultLanguage ) ;
   if ( Library == 0 ) {
      Process Proc ( PROGRAM_NAME, HWND_DESKTOP, 0 ) ;
      Debug ( HWND_DESKTOP, "ERROR: Unable to find language module for %s, %s, %s.", PROGRAM_NAME, REVISION, DefaultLanguage ) ;
      return ( 1 ) ;
   } /* endif */

   LibraryHandle = Library->QueryHandle() ;

  /**************************************************************************
   * Get the program title.                                                 *
   **************************************************************************/

   ResourceString Title ( Library->QueryHandle(), IDS_TITLE ) ;

  /**************************************************************************
   * Determine the default codepage.                                        *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Determining codepage to use." ) ;
   #endif // DEBUG

   PUSHORT pCodePage = Library->QueryCodepages() ;
   while ( *pCodePage ) {
      if ( !DosSetProcessCp ( *pCodePage ) )
         break ;
      pCodePage ++ ;
   } /* endwhile */

   if ( *pCodePage == 0 ) {
      ResourceString Format ( Library->QueryHandle(), IDS_WARNING_BADCODEPAGE ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), *Library->QueryCodepages() ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
         PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      return ( 1 ) ;
   } /* endif */
 
  /**************************************************************************
   * Initialize the process with an extra-large message queue.              *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Connecting to PM." ) ;
   #endif // DEBUG

   Process Proc ( PCHAR(Title), HWND_DESKTOP, Library->QueryHandle(), 100, *pCodePage ) ;
   if ( Proc.QueryAnchor() == 0 ) 
      return ( 1 ) ;

  /**************************************************************************
   * Register the custom control classes.                                   *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Registering custom control classes." ) ;
   #endif // DEBUG

   RegisterControls ( Proc.QueryAnchor() ) ;

  /**************************************************************************
   * Open up debug timer.                                                   *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Opening debug timer." ) ;
   #endif // DEBUG

   OpenTimer ( ) ;

  /**************************************************************************
   * Open the registration library, if it is present.                       *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to open registration file." ) ;
   #endif // DEBUG

   char *RegistrationName = PROGRAM_NAME"R" ;
   Module *pRegistration = new Module ( RegistrationName, FALSE ) ;
   if ( pRegistration->QueryHandle() == 0 )
      RegistrationName = "PLUMAR" ;
   delete pRegistration, pRegistration = 0 ;

   Module Registration = Module ( RegistrationName, FALSE ) ;

  /**************************************************************************
   * Load any extenders (except spell-check).                               *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to load extenders." ) ;
   #endif // DEBUG

   AddonList.Build ( DefaultLanguage ) ;

  /**************************************************************************
   * Get the country information.                                           *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to get country information." ) ;
   #endif // DEBUG

   GetCountryInfo ( 0, 0 ) ;

  /**************************************************************************
   * Set any language-specific globals.                                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to set language-specific globals." ) ;
   #endif // DEBUG

   ResourceString AllGraphicFiles ( LibraryHandle, IDS_ALL_GRAPHICS ) ;
   GraphicTypeList[0] = PSZ ( AllGraphicFiles ) ;

  /**************************************************************************
   * Check for command-line options and remove them from the argument list. *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to parse the command line." ) ;
   #endif // DEBUG

   ResourceString ResetCommand ( Library->QueryHandle(), IDS_PARMS_RESET ) ;
   BOOL Reset = FALSE ;

// ResourceString PrintCommand ( Library->QueryHandle(), IDS_PARMS_PRINT ) ;
// BOOL Print = FALSE ;

   ResourceString TrapCommand ( Library->QueryHandle(), IDS_PARMS_TRAP ) ;
   BOOL Trap = FALSE ;

   int i = 1 ;
   char **p = argv + 1 ;
   while ( i < argc ) {
      if ( **p == '-' ) {
         if ( !stricmp ( (*p)+1, PCHAR(ResetCommand) ) ) {
            Reset = TRUE ;
//       } else if ( !stricmp ( (*p)+1, PCHAR(PrintCommand) ) ) {
//          Print = TRUE ;
         } else if ( !stricmp ( (*p)+1, PCHAR(TrapCommand) ) ) {
            Trap = TRUE ;
         } else {
            Debug ( HWND_DESKTOP, "ERROR: Invalid command-line parameter '%s'.", (*p)+1 ) ;
            return ( 1 ) ;
         } /* endif */
         for ( int j=i+1; j<argc; j++ ) {
            argv[j-1] = argv[j] ;
         } /* endfor */
         argv[j] = 0 ;
         argc -- ;
         continue ;
      } /* endif */
      i ++ ;
      p ++ ;
   } /* endwhile */

  /**************************************************************************
   * Create the help instance.                                              *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to create the help instance." ) ;
   #endif // DEBUG

   _splitpath ( Library->QueryName(), Drive, Dir, Fname, Ext ) ;
   char HelpFileName [CCHMAXPATH] ;
   sprintf ( HelpFileName, "%s.hlp", Fname ) ;

   ResourceString HelpTitle ( Library->QueryHandle(), IDS_HELPTITLE ) ;

   Help = new HelpWindow ( Proc.QueryAnchor(), 0, ID_MAIN, PSZ(HelpFileName), PSZ(HelpTitle) ) ;

   if ( Help->QueryHandle() == 0 ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATEHELP ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
   } /* endif */

  /**************************************************************************
   * Open/create the profile file.  Reset if requested.                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to open profile file." ) ;
   #endif // DEBUG

   Profile2 IniFile ( PSZ(PROGRAM_NAME), Proc.QueryAnchor(), Library->QueryHandle(),
      IDD_PROFILE_PATH, Help, Reset ) ;

   if ( IniFile.QueryHandle() == 0 ) {
      ResourceString Message ( Library->QueryHandle(), IDS_ERROR_PRFOPENPROFILE ) ;
      Log ( "%s", PSZ(Message) ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer() ;
      return ( 2 ) ;
   } /* endif */

  /**************************************************************************
   * Get profile data. Try the OS2.INI first, then try for private INI.     *
   *   If obtained from OS2.INI, erase it afterwards and resave it.         *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to get profile data." ) ;
   #endif // DEBUG

   INIDATA IniData ( Registration.QueryHandle() ) ;
   IniFile.GetIniData ( IniData ) ;

   if ( IniData.Language [0] == 0 ) 
      strcpy ( IniData.Language, DefaultLanguage ) ;

  /**************************************************************************
   * Activate the spell checker, if it is present.                          *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to open the default dictionary." ) ;
   #endif // DEBUG

   char SpellerPath [ CCHMAXPATH ] = { 0 } ;
   if ( getenv ( "ISPELL" ) ) {
      strcpy ( SpellerPath, getenv ( "ISPELL" ) ) ;
      strcat ( SpellerPath, "\\" ) ;
   } /* endif */
   strcat ( SpellerPath, "ISPELLER.DLL" ) ;
   Dictionary *Speller = new Dictionary ( SpellerPath, DefaultLanguage ) ;
   if ( Speller->QueryLibrary() == 0 ) {
      #ifdef DEBUG
         Log ( "Escriba::main: Could not find spellchecker.  Will try again through LIBPATH." ) ;
      #endif // DEBUG
      delete Speller, Speller = 0 ;
      Speller = new Dictionary ( "ISPELLER", DefaultLanguage ) ;
   } /* endif */
   if ( Speller->Available() ) {
      #ifdef DEBUG
         Log ( "Escriba::main: Adding dictionary object to extension list." ) ;
      #endif // DEBUG
      AddonList.Add ( Speller ) ;
   } else {
      #ifdef DEBUG
         Log ( "Escriba::main: Dictionary object could not be fully created." ) ;
      #endif // DEBUG
      delete Speller, Speller = 0 ;
   } /* endif */

  /**************************************************************************
   * Create the frame window.                                               *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to create the frame window." ) ;
   #endif // DEBUG

   FRAMECDATA FrameControlData ;
   FrameControlData.cb = sizeof(FrameControlData) ;
   FrameControlData.flCreateFlags =
      FCF_TITLEBAR | FCF_MENU | FCF_ICON | FCF_NOBYTEALIGN | FCF_ACCELTABLE | FCF_SYSMENU |
      ( Trap ? 0 : FCF_SIZEBORDER | FCF_MINMAX ) ;
   FrameControlData.hmodResources = USHORT ( Library->QueryHandle() ) ;
   FrameControlData.idResources = ID_MAIN ;

   Window Frame ( HWND_DESKTOP, WC_FRAME, PSZ(Title),
      IniData.Animate ? WS_ANIMATE : 0,
      0, 0, 0, 0, HWND_DESKTOP, HWND_TOP, ID_MAIN,
      &FrameControlData, NULL ) ;

   if ( Frame.QueryHandle() == 0 ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATEFRAME ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message), PSZ(Title), 0, MB_ENTER | MB_ICONEXCLAMATION, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer() ;
      return ( 3 ) ;
   } /* endif */

  /**************************************************************************
   * Associate the help instance with the frame window.                     *
   **************************************************************************/

   Help->Associate ( Frame.QueryHandle() ) ;

  /**************************************************************************
   * Register the client window class.                                      *
   **************************************************************************/

   if ( !WinRegisterClass ( Proc.QueryAnchor(), PSZ(CLASS_NAME),
      MessageProcessor, CS_MOVENOTIFY, sizeof(PVOID) ) ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_WINREGISTERCLASS ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), CLASS_NAME, Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
         PSZ(Title), IDD_ERROR_WINREGISTERCLASS, MB_ENTER | MB_ICONEXCLAMATION | MB_HELP, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer() ;
      return ( 4 ) ;
   } /* endif */

  /**************************************************************************
   * Build the presentation parameters for the main window.                 *
   **************************************************************************/

   COLOR BackColor = IniData.fMainColors[0] ? IniData.MainColors[0] :
      WinQuerySysColor ( HWND_DESKTOP, SYSCLR_APPWORKSPACE, 0 ) ;
   ULONG Ids[] = { PP_BACKGROUNDCOLOR } ;
   ULONG ByteCounts[] = { sizeof(BackColor) } ;
   PUCHAR Params[] = { PUCHAR(&BackColor) } ;

   PPRESPARAMS PresParams = BuildPresParams ( sizeof(Ids)/sizeof(Ids[0]),
     Ids, ByteCounts, Params ) ;

  /**************************************************************************
   * Create client window.  If this fails, destroy frame and return.        *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to create the client window." ) ;
   #endif // DEBUG

   PARMS Parms ;
   Parms.Filler = 0 ;
   Parms.Library = Library ;
   Parms.Registration = & Registration ;
   Parms.IniFile = & IniFile ;
   Parms.IniData = & IniData ;
   Parms.Speller = Speller ;
   Parms.InitialPath = InitialPath ;
   Parms.argc = argc ;
   Parms.argv = argv ;
   Parms.Trap = Trap ;

   Window Client ( Frame.QueryHandle(), PSZ(CLASS_NAME), PSZ(""), WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
      0, 0, 0, 0, Frame.QueryHandle(), HWND_BOTTOM, FID_CLIENT, &Parms, PresParams ) ;

   free ( PresParams ) ;

   if ( Client.QueryHandle() == 0 ) {
      ERRORID Error = Sys_GetLastError ( Proc.QueryAnchor() ) ;
      ResourceString Format ( Library->QueryHandle(), IDS_ERROR_CREATECLIENT ) ;
      CHAR Message [200] ;
      sprintf ( Message, PCHAR(Format), Error ) ;
      Log ( "%s", Message ) ;
      MessageBox ( HWND_DESKTOP, HWND_DESKTOP, PSZ(Message),
         PSZ(Title), IDD_ERROR_CREATECLIENT, MB_ENTER | MB_ICONEXCLAMATION | MB_HELP, LibraryHandle, IDS_MESSAGE_BOX_STRINGS ) ;
      CloseTimer ( ) ;
      return ( 5 ) ;
   } /* endif */

   ((SHARED_MEMORY*)Memory.QueryMemory())->MainWindow = Client.QueryHandle() ;

  /**************************************************************************
   * Wait for and process messages to the window's queue.  Terminate        *
   *   when the WM_QUIT message is received.                                *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to enter the main message loop." ) ;
   #endif // DEBUG

   Sys_ProcessMessages ( Proc.QueryAnchor() ) ;

  /**************************************************************************
   * Discard all that had been requested of the system.                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: About to close the HR Timer." ) ;
   #endif // DEBUG

   CloseTimer ( ) ;

  /**************************************************************************
   * Invoke nearly all the destructors.                                     *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Invoking most destructors." ) ;
   #endif // DEBUG

   } /* Invoke all destructors except the global ones. */

  /**************************************************************************
   * Invoke the remaining destructors.                                      *
   **************************************************************************/

   #ifdef DEBUG
      Log ( "Escriba::main: Clearing the addon list." ) ;
   #endif // DEBUG

   AddonList.Clear ( ) ;

   #ifdef DEBUG
      Log ( "Escriba::main: Clearing the file type list." ) ;
   #endif // DEBUG

   ClearFileTypeList ( ) ;

   #ifdef DEBUG
      Log ( "Escriba::main: Clearing the graphic type list." ) ;
   #endif // DEBUG

   ClearGraphicTypeList ( ) ;

   #ifdef DEBUG
      Log ( "Escriba::main: Destroying the help instance." ) ;
   #endif // DEBUG

   if ( Help ) delete Help ;

   #ifdef DEBUG
      Log ( "Escriba::main: Destroying the language library instance." ) ;
   #endif // DEBUG

   if ( Library ) delete Library ;

  /**************************************************************************
   * Check to see if any memory remains allocated.                          *
   **************************************************************************/

   #ifdef __DEBUG_ALLOC__
      Log ( "Escriba::main: Checking the heap." ) ;
      _dump_allocated ( 64 ) ;
      Log ( "Escriba::main: Program ended." ) ;
      fclose ( Logfile ) ;
   #else
      #ifdef DEBUG
         Log ( "Escriba::main: Program ended." ) ;
      #endif // DEBUG
   #endif // __DEBUG_ALLOC__

  /**************************************************************************
   * Discard the exception filter.                                          *
   **************************************************************************/

   UNREGISTER_EXCEPTION_HANDLER(0);

  /**************************************************************************
   * Terminate the process.                                                 *
   **************************************************************************/

   return ( 0 ) ;
}
예제 #5
0
파일: SBFrame.cpp 프로젝트: filcab/lldb
lldb::SBValue
SBFrame::EvaluateExpression (const char *expr, const SBExpressionOptions &options)
{
    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    LogSP expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    ExecutionResults exe_results = eExecutionSetupError;
    SBValue expr_result;
    
    if (expr == NULL || expr[0] == '\0')
    {
        if (log)
            log->Printf ("SBFrame::EvaluateExpression called with an empty expression");
        return expr_result;
    }
    
    ValueObjectSP expr_value_sp;

    Mutex::Locker api_locker;
    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);

    if (log)
        log->Printf ("SBFrame()::EvaluateExpression (expr=\"%s\")...", expr);

    StackFrame *frame = NULL;
    Target *target = exe_ctx.GetTargetPtr();
    Process *process = exe_ctx.GetProcessPtr();
    
    if (target && process)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process->GetRunLock()))
        {
            frame = exe_ctx.GetFramePtr();
            if (frame)
            {
#ifdef LLDB_CONFIGURATION_DEBUG
                StreamString frame_description;
                frame->DumpUsingSettingsFormat (&frame_description);
                Host::SetCrashDescriptionWithFormat ("SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
                                                     expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str());
#endif
                exe_results = target->EvaluateExpression (expr, 
                                                          frame,
                                                          expr_value_sp,
                                                          options.ref());
                expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
#ifdef LLDB_CONFIGURATION_DEBUG
                Host::SetCrashDescription (NULL);
#endif
            }
            else
            {
                if (log)
                    log->Printf ("SBFrame::EvaluateExpression () => error: could not reconstruct frame object for this SBFrame.");
            }
        }
        else
        {
            if (log)
                log->Printf ("SBFrame::EvaluateExpression () => error: process is running");
        }            
    }

#ifndef LLDB_DISABLE_PYTHON
    if (expr_log)
        expr_log->Printf("** [SBFrame::EvaluateExpression] Expression result is %s, summary %s **", 
                         expr_result.GetValue(), 
                         expr_result.GetSummary());
    
    if (log)
        log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)", 
                     frame, 
                     expr, 
                     expr_value_sp.get(),
                     exe_results);
#endif

    return expr_result;
}
예제 #6
0
Error
ClangExpressionParser::DisassembleFunction (Stream &stream, ExecutionContext &exe_ctx, RecordingMemoryManager *jit_memory_manager)
{
    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    
    const char *name = m_expr.FunctionName();
    
    Error ret;
    
    ret.Clear();
    
    lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
    lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;
    
    std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end();
    
    for (pos = m_jitted_functions.begin(); pos < end; pos++)
    {
        if (strstr(pos->m_name.c_str(), name))
        {
            func_local_addr = pos->m_local_addr;
            func_remote_addr = pos->m_remote_addr;
        }
    }
    
    if (func_local_addr == LLDB_INVALID_ADDRESS)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", name);
        return ret;
    }
    
    if (log)
        log->Printf("Found function, has local address 0x%llx and remote address 0x%llx", (uint64_t)func_local_addr, (uint64_t)func_remote_addr);
    
    std::pair <lldb::addr_t, lldb::addr_t> func_range;
    
    func_range = jit_memory_manager->GetRemoteRangeForLocal(func_local_addr);
    
    if (func_range.first == 0 && func_range.second == 0)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't find code range for function %s", name);
        return ret;
    }
    
    if (log)
        log->Printf("Function's code range is [0x%llx+0x%llx]", func_range.first, func_range.second);
    
    Target *target = exe_ctx.GetTargetPtr();
    if (!target)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorString("Couldn't find the target");
    }
    
    lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));
    
    Process *process = exe_ctx.GetProcessPtr();
    Error err;
    process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);
    
    if (!err.Success())
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
        return ret;
    }
    
    ArchSpec arch(target->GetArchitecture());
    
    Disassembler *disassembler = Disassembler::FindPlugin(arch, NULL);
    
    if (disassembler == NULL)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
        return ret;
    }
    
    if (!process)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorString("Couldn't find the process");
        return ret;
    }
    
    DataExtractor extractor(buffer_sp, 
                            process->GetByteOrder(),
                            target->GetArchitecture().GetAddressByteSize());
    
    if (log)
    {
        log->Printf("Function data has contents:");
        extractor.PutToLog (log.get(),
                            0,
                            extractor.GetByteSize(),
                            func_remote_addr,
                            16,
                            DataExtractor::TypeUInt8);
    }
    
    disassembler->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false);
    
    InstructionList &instruction_list = disassembler->GetInstructionList();
    const uint32_t max_opcode_byte_size = instruction_list.GetMaxOpcocdeByteSize();
    for (uint32_t instruction_index = 0, num_instructions = instruction_list.GetSize(); 
         instruction_index < num_instructions; 
         ++instruction_index)
    {
        Instruction *instruction = instruction_list.GetInstructionAtIndex(instruction_index).get();
        instruction->Dump (&stream,
                           max_opcode_byte_size,
                           true,
                           true,
                           &exe_ctx);
        stream.PutChar('\n');
    }
    
    return ret;
}
예제 #7
0
//----------------------------------------------------------------------
// Static callback function that gets called when our DYLD notification
// breakpoint gets hit. We update all of our image infos and then
// let our super class DynamicLoader class decide if we should stop
// or not (based on global preference).
//----------------------------------------------------------------------
bool DynamicLoaderMacOSXDYLD::NotifyBreakpointHit(
    void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id,
    lldb::user_id_t break_loc_id) {
  // Let the event know that the images have changed
  // DYLD passes three arguments to the notification breakpoint.
  // Arg1: enum dyld_image_mode mode - 0 = adding, 1 = removing
  // Arg2: uint32_t infoCount        - Number of shared libraries added
  // Arg3: dyld_image_info info[]    - Array of structs of the form:
  //                                     const struct mach_header
  //                                     *imageLoadAddress
  //                                     const char               *imageFilePath
  //                                     uintptr_t imageFileModDate (a time_t)

  DynamicLoaderMacOSXDYLD *dyld_instance = (DynamicLoaderMacOSXDYLD *)baton;

  // First step is to see if we've already initialized the all image infos.  If
  // we haven't then this function
  // will do so and return true.  In the course of initializing the
  // all_image_infos it will read the complete
  // current state, so we don't need to figure out what has changed from the
  // data passed in to us.

  ExecutionContext exe_ctx(context->exe_ctx_ref);
  Process *process = exe_ctx.GetProcessPtr();

  // This is a sanity check just in case this dyld_instance is an old dyld
  // plugin's breakpoint still lying around.
  if (process != dyld_instance->m_process)
    return false;

  if (dyld_instance->InitializeFromAllImageInfos())
    return dyld_instance->GetStopWhenImagesChange();

  const lldb::ABISP &abi = process->GetABI();
  if (abi) {
    // Build up the value array to store the three arguments given above, then
    // get the values from the ABI:

    ClangASTContext *clang_ast_context =
        process->GetTarget().GetScratchClangASTContext();
    ValueList argument_values;
    Value input_value;

    CompilerType clang_void_ptr_type =
        clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
    CompilerType clang_uint32_type =
        clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
            lldb::eEncodingUint, 32);
    input_value.SetValueType(Value::eValueTypeScalar);
    input_value.SetCompilerType(clang_uint32_type);
    //        input_value.SetContext (Value::eContextTypeClangType,
    //        clang_uint32_type);
    argument_values.PushValue(input_value);
    argument_values.PushValue(input_value);
    input_value.SetCompilerType(clang_void_ptr_type);
    //        input_value.SetContext (Value::eContextTypeClangType,
    //        clang_void_ptr_type);
    argument_values.PushValue(input_value);

    if (abi->GetArgumentValues(exe_ctx.GetThreadRef(), argument_values)) {
      uint32_t dyld_mode =
          argument_values.GetValueAtIndex(0)->GetScalar().UInt(-1);
      if (dyld_mode != static_cast<uint32_t>(-1)) {
        // Okay the mode was right, now get the number of elements, and the
        // array of new elements...
        uint32_t image_infos_count =
            argument_values.GetValueAtIndex(1)->GetScalar().UInt(-1);
        if (image_infos_count != static_cast<uint32_t>(-1)) {
          // Got the number added, now go through the array of added elements,
          // putting out the mach header
          // address, and adding the image.
          // Note, I'm not putting in logging here, since the AddModules &
          // RemoveModules functions do
          // all the logging internally.

          lldb::addr_t image_infos_addr =
              argument_values.GetValueAtIndex(2)->GetScalar().ULongLong();
          if (dyld_mode == 0) {
            // This is add:
            dyld_instance->AddModulesUsingImageInfosAddress(image_infos_addr,
                                                            image_infos_count);
          } else {
            // This is remove:
            dyld_instance->RemoveModulesUsingImageInfosAddress(
                image_infos_addr, image_infos_count);
          }
        }
      }
    }
  } else {
    process->GetTarget().GetDebugger().GetAsyncErrorStream()->Printf(
        "No ABI plugin located for triple %s -- shared libraries will not be "
        "registered!\n",
        process->GetTarget().GetArchitecture().GetTriple().getTriple().c_str());
  }

  // Return true to stop the target, false to just let the target run
  return dyld_instance->GetStopWhenImagesChange();
}
bool ValueObjectDynamicValue::UpdateValue() {
  SetValueIsValid(false);
  m_error.Clear();

  if (!m_parent->UpdateValueIfNeeded(false)) {
    // The dynamic value failed to get an error, pass the error along
    if (m_error.Success() && m_parent->GetError().Fail())
      m_error = m_parent->GetError();
    return false;
  }

  // Setting our type_sp to NULL will route everything back through our parent
  // which is equivalent to not using dynamic values.
  if (m_use_dynamic == lldb::eNoDynamicValues) {
    m_dynamic_type_info.Clear();
    return true;
  }

  ExecutionContext exe_ctx(GetExecutionContextRef());
  Target *target = exe_ctx.GetTargetPtr();
  if (target) {
    m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
    m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
  }

  // First make sure our Type and/or Address haven't changed:
  Process *process = exe_ctx.GetProcessPtr();
  if (!process)
    return false;

  TypeAndOrName class_type_or_name;
  Address dynamic_address;
  bool found_dynamic_type = false;
  Value::ValueType value_type;

  LanguageRuntime *runtime = nullptr;

  lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
  if (known_type != lldb::eLanguageTypeUnknown &&
      known_type != lldb::eLanguageTypeC) {
    runtime = process->GetLanguageRuntime(known_type);
    if (runtime)
      found_dynamic_type = runtime->GetDynamicTypeAndAddress(
          *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
          value_type);
  } else {
    runtime = process->GetLanguageRuntime(lldb::eLanguageTypeC_plus_plus);
    if (runtime)
      found_dynamic_type = runtime->GetDynamicTypeAndAddress(
          *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
          value_type);

    if (!found_dynamic_type) {
      runtime = process->GetLanguageRuntime(lldb::eLanguageTypeObjC);
      if (runtime)
        found_dynamic_type = runtime->GetDynamicTypeAndAddress(
            *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
            value_type);
    }
  }

  // Getting the dynamic value may have run the program a bit, and so marked us
  // as needing updating, but we really don't...

  m_update_point.SetUpdated();

  if (runtime && found_dynamic_type) {
    if (class_type_or_name.HasType()) {
      m_type_impl =
          TypeImpl(m_parent->GetCompilerType(),
                   runtime->FixUpDynamicType(class_type_or_name, *m_parent)
                       .GetCompilerType());
    } else {
      m_type_impl.Clear();
    }
  } else {
    m_type_impl.Clear();
  }

  // If we don't have a dynamic type, then make ourselves just a echo of our
  // parent. Or we could return false, and make ourselves an echo of our
  // parent?
  if (!found_dynamic_type) {
    if (m_dynamic_type_info)
      SetValueDidChange(true);
    ClearDynamicTypeInformation();
    m_dynamic_type_info.Clear();
    m_value = m_parent->GetValue();
    m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
    return m_error.Success();
  }

  Value old_value(m_value);

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));

  bool has_changed_type = false;

  if (!m_dynamic_type_info) {
    m_dynamic_type_info = class_type_or_name;
    has_changed_type = true;
  } else if (class_type_or_name != m_dynamic_type_info) {
    // We are another type, we need to tear down our children...
    m_dynamic_type_info = class_type_or_name;
    SetValueDidChange(true);
    has_changed_type = true;
  }

  if (has_changed_type)
    ClearDynamicTypeInformation();

  if (!m_address.IsValid() || m_address != dynamic_address) {
    if (m_address.IsValid())
      SetValueDidChange(true);

    // We've moved, so we should be fine...
    m_address = dynamic_address;
    lldb::TargetSP target_sp(GetTargetSP());
    lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
    m_value.GetScalar() = load_address;
  }

  if (runtime)
    m_dynamic_type_info =
        runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);

  // m_value.SetContext (Value::eContextTypeClangType, corrected_type);
  m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType());

  m_value.SetValueType(value_type);

  if (has_changed_type && log)
    log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
                static_cast<void *>(this), GetTypeName().GetCString());

  if (m_address.IsValid() && m_dynamic_type_info) {
    // The variable value is in the Scalar value inside the m_value. We can
    // point our m_data right to it.
    m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
    if (m_error.Success()) {
      if (!CanProvideValue()) {
        // this value object represents an aggregate type whose children have
        // values, but this object does not. So we say we are changed if our
        // location has changed.
        SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
                          m_value.GetScalar() != old_value.GetScalar());
      }

      SetValueIsValid(true);
      return true;
    }
  }

  // We get here if we've failed above...
  SetValueIsValid(false);
  return false;
}
예제 #9
0
// thread for receiving ACK messages from ONE participant
void* ReceiveAckFromParticipant(void* _rcv_thread_arg) {
    ReceiveThreadArgument *rcv_thread_arg = (ReceiveThreadArgument *)_rcv_thread_arg;
    int pid = rcv_thread_arg->pid;
    int tid = rcv_thread_arg->transaction_id;
    string msg1 = rcv_thread_arg->expected_msg1;    //ACK
    string msg2 = rcv_thread_arg->expected_msg2;    //NULL
    Process *p = rcv_thread_arg->p;

    char buf[kMaxDataSize];
    int num_bytes;
    //TODO: write code to extract multiple messages

    fd_set temp_set;
    FD_ZERO(&temp_set);
    FD_SET(p->get_fd(pid), &temp_set);
    int fd_max = p->get_fd(pid);
    int rv;
    rv = select(fd_max + 1, &temp_set, NULL, NULL, (timeval*)&kTimeout);
    if (rv == -1) { //error in select
        // cout << "P" << p->get_pid() << ": ERROR in select() for P" << pid << strerror(errno)<< endl;
        rcv_thread_arg->received_msg_type = TIMEOUT;
        p->RemoveFromUpSet(pid);
    } else if (rv == 0) {   //timeout
        rcv_thread_arg->received_msg_type = TIMEOUT;
        p->RemoveFromUpSet(pid);
    } else {    // activity happened on the socket
        if ((num_bytes = recv(p->get_fd(pid), buf, kMaxDataSize - 1, 0)) == -1) {
            // cout << "P" << p->get_pid() << ": ERROR in receiving for P" << pid << endl;
            rcv_thread_arg->received_msg_type = TIMEOUT;
            p->RemoveFromUpSet(pid);
        } else if (num_bytes == 0) {     //connection closed
            // cout << "P" << p->get_pid() << ": Connection closed by P" << pid << endl;
            // if participant closes connection, it is equivalent to it crashing
            // can treat it as TIMEOUT
            // TODO: verify argument
            rcv_thread_arg->received_msg_type = TIMEOUT;
            p->RemoveFromUpSet(pid);
            //TODO: handle connection close based on different cases
        } else {
            buf[num_bytes] = '\0';
            cout << "P" << p->get_pid() << ": ACK received from P" << pid <<  endl;

            string extracted_msg;
            int received_tid;
            // in this case, we don't care about the received_tid,
            // because it will surely be for the transaction under consideration
            p->ExtractMsg(string(buf), extracted_msg, received_tid);

            if (extracted_msg == msg1) {    // it's an ACK
                rcv_thread_arg->received_msg_type = ACK;
            } else {
                //TODO: take actions appropriately, like check log for previous transaction decision.
                timeval timeofday;
                gettimeofday(&timeofday, NULL);
                cout << "P" << p->get_pid() << ": Expecting ack. Unexpected msg received from P" << pid << buf<< " at "<<timeofday.tv_sec<<"."<<timeofday.tv_usec<<endl;

                rcv_thread_arg->received_msg_type = ERROR;
            }
        }
    }
    // cout << "P" << p->get_pid() << ": Receive thread exiting for P" << pid << endl;
    return NULL;
}
예제 #10
0
파일: Maps.cpp 프로젝트: zilpin/dfhack
Maps::Maps(DFContextShared* _d)
{
    d = new Private;
    d->d = _d;
    Process *p = d->owner = _d->p;
    d->Inited = d->FeaturesStarted = d->Started = false;
    d->block = NULL;
    d->usesWorldDataPtr = false;

    DFHack::VersionInfo * mem = p->getDescriptor();
    Private::t_offsets &off = d->offsets;
    d->hasFeatures = d->hasGeology = d->hasVeggies = true;

    // get the offsets once here
    OffsetGroup *OG_Maps = mem->getGroup("Maps");
    try
    {
        off.world_data = OG_Maps->getAddress("world_data");
        d->usesWorldDataPtr = true;
        //cout << "uses world ptr" << endl;
    }catch(Error::AllMemdef &){}

    {
        off.map_offset = OG_Maps->getAddress ("map_data");
        off.x_count_offset = OG_Maps->getAddress ("x_count_block");
        off.y_count_offset = OG_Maps->getAddress ("y_count_block");
        off.z_count_offset = OG_Maps->getAddress ("z_count_block");
        off.region_x_offset = OG_Maps->getAddress ("region_x");
        off.region_y_offset = OG_Maps->getAddress ("region_y");
        off.region_z_offset =  OG_Maps->getAddress ("region_z");
        if(d->usesWorldDataPtr)
        {
            off.world_size_x = OG_Maps->getOffset ("world_size_x_from_wdata");
            off.world_size_y = OG_Maps->getOffset ("world_size_y_from_wdata");
        }
        else
        {
            off.world_size_x = OG_Maps->getAddress ("world_size_x");
            off.world_size_y = OG_Maps->getAddress ("world_size_y");
        }
        OffsetGroup *OG_MapBlock = OG_Maps->getGroup("block");
        {
            off.tile_type_offset = OG_MapBlock->getOffset ("type");
            off.designation_offset = OG_MapBlock->getOffset ("designation");
            off.occupancy_offset = OG_MapBlock->getOffset("occupancy");
            off.biome_stuffs = OG_MapBlock->getOffset ("biome_stuffs");
            off.veinvector = OG_MapBlock->getOffset ("vein_vector");
            off.local_feature_offset = OG_MapBlock->getOffset ("feature_local");
            off.global_feature_offset = OG_MapBlock->getOffset ("feature_global");
            off.temperature1_offset = OG_MapBlock->getOffset ("temperature1");
            off.temperature2_offset = OG_MapBlock->getOffset ("temperature2");
        }
        try
        {
            off.mystery = OG_MapBlock->getOffset ("mystery_offset");
        }
        catch(Error::AllMemdef &)
        {
            off.mystery = 0;
        }
        try
        {
            OffsetGroup *OG_Geology = OG_Maps->getGroup("geology");
            if(d->usesWorldDataPtr)
            {
                off.world_regions =  OG_Geology->getOffset ("ptr2_region_array_from_wdata");
                off.world_geoblocks_vector =  OG_Geology->getOffset ("geoblock_vector_from_wdata");
            }
            else
            {
                off.world_regions =  OG_Geology->getAddress ("ptr2_region_array");
                off.world_geoblocks_vector =  OG_Geology->getAddress ("geoblock_vector");
            }
            off.region_size =  OG_Geology->getHexValue ("region_size");
            off.region_geo_index_offset =  OG_Geology->getOffset ("region_geo_index_off");
            off.geolayer_geoblock_offset = OG_Geology->getOffset ("geolayer_geoblock_offset");
            off.type_inside_geolayer = OG_Geology->getOffset ("type_inside_geolayer");
        }
        catch(Error::AllMemdef &)
        {
            d->hasGeology = false;
        }
        OffsetGroup *OG_global_features = OG_Maps->getGroup("features")->getGroup("global");
        OffsetGroup *OG_local_features = OG_Maps->getGroup("features")->getGroup("local");
        try
        {
            if(d->usesWorldDataPtr)
            {
                off.local_f_start = OG_local_features->getOffset("start_ptr_from_wdata");
                off.global_vector = OG_global_features->getOffset("vector_from_wdata");
            }
            else
            {
                off.local_f_start = OG_local_features->getAddress("start_ptr");
                off.global_vector = OG_global_features->getAddress("vector");
            }
            off.local_material = OG_local_features->getOffset("material");
            off.local_submaterial = OG_local_features->getOffset("submaterial");

            off.global_funcptr =  OG_global_features->getOffset("funcptr");
            off.global_material =  OG_global_features->getOffset("material");
            off.global_submaterial =  OG_global_features->getOffset("submaterial");
        }
        catch(Error::AllMemdef &)
        {
            d->hasFeatures = false;
        }

        try
        {
            OffsetGroup * OG_Veg = d->d->offset_descriptor->getGroup("Vegetation");
            off.vegvector = OG_MapBlock->getOffset ("vegetation_vector");
            off.tree_desc_offset = OG_Veg->getOffset ("tree_desc_offset");
        }
        catch(Error::AllMemdef &)
        {
            d->hasVeggies = false;
        }
    }
    d->OG_vector = mem->getGroup("vector");

    // these can (will) fail and will be found when looking at the actual veins later
    // basically a cache
    off.vein_ice_vptr = 0;
    mem->resolveClassnameToVPtr("block_square_event_frozen_liquid", off.vein_ice_vptr);
    off.vein_mineral_vptr = 0;
    mem->resolveClassnameToVPtr("block_square_event_mineral",off.vein_mineral_vptr);
    off.vein_spatter_vptr = 0;
    mem->resolveClassnameToVPtr("block_square_event_material_spatterst",off.vein_spatter_vptr);
    off.vein_grass_vptr = 0;
    mem->resolveClassnameToVPtr("block_square_event_grassst",off.vein_grass_vptr);
    off.vein_worldconstruction_vptr = 0;
    mem->resolveClassnameToVPtr("block_square_event_world_constructionst",off.vein_worldconstruction_vptr);

    d->Inited = true;
}
예제 #11
0
bool
ValueObjectVariable::UpdateValue ()
{
    SetValueIsValid (false);
    m_error.Clear();

    Variable *variable = m_variable_sp.get();
    DWARFExpression &expr = variable->LocationExpression();
    
    if (variable->GetLocationIsConstantValueData())
    {
        // expr doesn't contain DWARF bytes, it contains the constant variable
        // value bytes themselves...
        if (expr.GetExpressionData(m_data))
            m_value.SetContext(Value::eContextTypeVariable, variable);
        else
            m_error.SetErrorString ("empty constant data");
        // constant bytes can't be edited - sorry
        m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
    }
    else
    {
        lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
        ExecutionContext exe_ctx (GetExecutionContextRef());
        
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
        {
            m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
            m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
        }

        if (expr.IsLocationList())
        {
            SymbolContext sc;
            variable->CalculateSymbolContext (&sc);
            if (sc.function)
                loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
        }
        Value old_value(m_value);
        if (expr.Evaluate (&exe_ctx, NULL, NULL, NULL, loclist_base_load_addr, NULL, m_value, &m_error))
        {
            m_resolved_value = m_value;
            m_value.SetContext(Value::eContextTypeVariable, variable);
            
            ClangASTType clang_type = GetClangType();
            if (clang_type.IsValid())
                m_value.SetClangType(clang_type);

            Value::ValueType value_type = m_value.GetValueType();
            
            switch (value_type)
            {
                case Value::eValueTypeFileAddress:
                    SetAddressTypeOfChildren(eAddressTypeFile);
                    break;
                case Value::eValueTypeHostAddress:
                    SetAddressTypeOfChildren(eAddressTypeHost);
                    break;
                case Value::eValueTypeLoadAddress:
                case Value::eValueTypeScalar:
                case Value::eValueTypeVector:
                    SetAddressTypeOfChildren(eAddressTypeLoad);
                    break;
            }

            switch (value_type)
            {
            case Value::eValueTypeVector:
                    // fall through
            case Value::eValueTypeScalar:
                // The variable value is in the Scalar value inside the m_value.
                // We can point our m_data right to it.
                m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
                break;

            case Value::eValueTypeFileAddress:
            case Value::eValueTypeLoadAddress:
            case Value::eValueTypeHostAddress:
                // The DWARF expression result was an address in the inferior
                // process. If this variable is an aggregate type, we just need
                // the address as the main value as all child variable objects
                // will rely upon this location and add an offset and then read
                // their own values as needed. If this variable is a simple
                // type, we read all data for it into m_data.
                // Make sure this type has a value before we try and read it

                // If we have a file address, convert it to a load address if we can.
                Process *process = exe_ctx.GetProcessPtr();
                if (value_type == Value::eValueTypeFileAddress && process && process->IsAlive())
                {
                    lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
                    if (file_addr != LLDB_INVALID_ADDRESS)
                    {
                        SymbolContext var_sc;
                        variable->CalculateSymbolContext(&var_sc);
                        if (var_sc.module_sp)
                        {
                            ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
                            if (objfile)
                            {
                                Address so_addr(file_addr, objfile->GetSectionList());
                                lldb::addr_t load_addr = so_addr.GetLoadAddress (target);
                                if (load_addr != LLDB_INVALID_ADDRESS)
                                {
                                    m_value.SetValueType(Value::eValueTypeLoadAddress);
                                    m_value.GetScalar() = load_addr;
                                }
                            }
                        }
                    }
                }

                if (!CanProvideValue())
                {
                    // this value object represents an aggregate type whose
                    // children have values, but this object does not. So we
                    // say we are changed if our location has changed.
                    SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
                }
                else
                {
                    // Copy the Value and set the context to use our Variable
                    // so it can extract read its value into m_data appropriately
                    Value value(m_value);
                    value.SetContext(Value::eContextTypeVariable, variable);
                    m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
                    
                    SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
                }
                break;
            }

            SetValueIsValid (m_error.Success());
        }
        else
        {
            // could not find location, won't allow editing
            m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
        }
    }
    return m_error.Success();
}
예제 #12
0
파일: hirdrgen.cpp 프로젝트: jlaura/isis3
void IsisMain() {

  QString projName;

  Process pHist;
  Cube *icube = pHist.SetInputCube("FROM");

  // Check to see if the input cube looks like a HiRISE RDR
  if (icube->bandCount() > 3) {
    QString msg = "Input file [" +
                 Application::GetUserInterface().GetFileName("FROM") +
                 "] does not appear to be a HiRISE RDR product. Number of " +
                 "bands is greater than 3";
    throw IException(IException::Programmer, msg, _FILEINFO_);
  }

  // Setup to get a histogram for each band
  g_min = new double[icube->bandCount()];
  g_max = new double[icube->bandCount()];

  UserInterface &ui = Application::GetUserInterface();

  // Determine if the data is to be converted to JPEG2000
  IString enctype = ui.GetString("ENCODING_TYPE");
  enctype.DownCase();

  for (int band = 1; band <= icube->bandCount(); ++band) {

    if (ui.GetString("TYPE").compare("AUTOMATIC") == 0) {
      // Set up a histogram for this band. This call sets the input range
      // by making an initial stats pass to find the data min and max
      Histogram hist(*icube, band, pHist.Progress());

      // Loop and accumulate histogram
      pHist.Progress()->SetText("Gathering Histogram");
      pHist.Progress()->SetMaximumSteps(icube->lineCount());
      pHist.Progress()->CheckStatus();
      LineManager line(*icube);
      for (int i = 1; i <= icube->lineCount(); i++) {
        line.SetLine(i, band);
        icube->read(line);
        hist.AddData(line.DoubleBuffer(), line.size());
        pHist.Progress()->CheckStatus();
      }

      // get the requested cumulative percentages
      g_min[band-1] = ui.GetDouble("MINPER") == 0.0 ? hist.Minimum() : hist.Percent(ui.GetDouble("MINPER"));
      g_max[band-1] = ui.GetDouble("MAXPER") == 100.0 ? hist.Maximum() : hist.Percent(ui.GetDouble("MAXPER"));
    }
    else {
      g_min[band-1] = ui.GetDouble("MIN");
      g_max[band-1] = ui.GetDouble("MAX");
    }
  }

  // Find the minimum min and maximum max for all bands
  double minmin = g_min[0];
  double maxmax = g_max[0];
  for (int band = 1; band < icube->bandCount(); ++band) {
    if (g_min[band] < minmin) minmin = g_min[band];
    if (g_max[band] > maxmax) maxmax = g_max[band];
  }

  pHist.EndProcess();

  // Set up for writing the data to a PDS formatted file
  ProcessExportPds p;
  Cube *icube2 = p.SetInputCube("FROM");

  if (enctype.Equal("jp2")) {
    g_jp2buf = new char* [icube2->bandCount()];
    FileName lblFile(ui.GetFileName("TO"));
    QString lblFileName = lblFile.path() + "/" + lblFile.baseName() + ".lbl";
    p.SetDetached(lblFileName);
    p.setFormat(ProcessExport::JP2);
  }

  // Set the output pixel type and the special pixel values
  int nbits = ui.GetInteger("BITS");
  if (nbits == 8) {
    if (enctype.Equal("jp2")) {
      for (int i = 0; i < icube2->bandCount(); i++) {
        g_jp2buf[i] = new char[icube2->sampleCount()];
      }
    }
    g_oType = Isis::UnsignedByte;
    p.SetOutputType(g_oType);
    p.SetOutputRange(VALID_MIN1, VALID_MAX1);
    p.SetOutputNull(NULL1);
    p.SetOutputLis(LOW_INSTR_SAT1);
    p.SetOutputLrs(LOW_REPR_SAT1);
    p.SetOutputHis(HIGH_INSTR_SAT1);
    p.SetOutputHrs(HIGH_REPR_SAT1);
  }
  else if (nbits == 16) {
    if (enctype.Equal("jp2")) {
      for (int i = 0; i < icube2->bandCount(); i++) {
        g_jp2buf[i] = new char[icube2->sampleCount()*2];
      }
    }
    g_oType = UnsignedWord;
    p.SetOutputType(g_oType);
    p.SetOutputRange(VALID_MINU2, VALID_MAXU2);
    p.SetOutputNull(NULLU2);
    p.SetOutputLis(LOW_INSTR_SATU2);
    p.SetOutputLrs(LOW_REPR_SATU2);
    p.SetOutputHis(HIGH_INSTR_SATU2);
    p.SetOutputHrs(HIGH_REPR_SATU2);
  }
  else {
    if (enctype.Equal("jp2")) {
      for (int i = 0; i < icube2->bandCount(); i++) {
        g_jp2buf[i] = new char[icube2->sampleCount()*2];
      }
    }
    g_oType = UnsignedWord;
    p.SetOutputType(g_oType);
    p.SetOutputRange(3.0, pow(2.0, (double)(nbits)) - 1.0 - 2.0);
    p.SetOutputNull(0);
    p.SetOutputLrs(1);
    p.SetOutputLis(2);
    p.SetOutputHis(pow(2.0, (double)(nbits)) - 1.0 - 1.0);
    p.SetOutputHrs(pow(2.0, (double)(nbits)) - 1.0);
  }
  p.SetOutputEndian(Isis::Msb);
  p.SetInputRange(minmin, maxmax);

  // Get the PDS label from the process
  ProcessExportPds::PdsFileType type;
  if (enctype.Equal("jp2")) {
    type = ProcessExportPds::JP2Image;
  }
  else {
    type = ProcessExportPds::Image;
  }
  Pvl &pdsLabel = p.StandardPdsLabel(type);

  // Translate the keywords from the input cube label that go in the PDS label
  PvlTranslationManager cubeLab(*(icube2->label()),
                                "$mro/translations/hirisePdsRdrCubeLabel.trn");
  cubeLab.Auto(pdsLabel);

  // Translate the keywords from the original EDR PDS label that go in
  // this RDR PDS label
  OriginalLabel origBlob;
  icube2->read(origBlob);
  Pvl origLabel;
  PvlObject origLabelObj = origBlob.ReturnLabels();
  origLabelObj.setName("OriginalLabelObject");
  origLabel.addObject(origLabelObj);
  PvlTranslationManager orig(origLabel,
                             "$mro/translations/hirisePdsRdrOriginalLabel.trn");
  orig.Auto(pdsLabel);

  // Add labels to the PDS product that could not be handled by the translater

  if (ui.WasEntered("RATIONALE_DESC")) {
    pdsLabel.addKeyword(
        PvlKeyword("RATIONALE_DESC", ui.GetString("RATIONALE_DESC")),
        Pvl::Replace);
  }

  // Add PRODUCT_CREATION_TIME
  time_t startTime = time(NULL);
  struct tm *tmbuf = gmtime(&startTime);
  char timestr[80];
  strftime(timestr, 80, "%Y-%m-%dT%H:%M:%S", tmbuf);
  QString dateTime = (QString) timestr;
  iTime tmpDateTime(dateTime);
  PvlGroup &timeParam = pdsLabel.findGroup("TIME_PARAMETERS");
  timeParam += PvlKeyword("PRODUCT_CREATION_TIME", tmpDateTime.UTC());

  // Add the N/A constant keyword to the ROOT
  pdsLabel += PvlKeyword("NOT_APPLICABLE_CONSTANT", toString(-9998));

  // Add SOFTWARE_NAME to the ROOT
  QString sfname;
  sfname.clear();
  sfname += "Isis " + Application::Version() + " " +
            Application::GetUserInterface().ProgramName();
  pdsLabel += PvlKeyword("SOFTWARE_NAME", sfname);

  // Add the PRODUCT_VERSION_ID from the user parameter VERSION
  pdsLabel += PvlKeyword("PRODUCT_VERSION_ID", ui.GetString("VERSION"));

  // Add MRO:CCD_FLAG, MRO:BINNING, MRO:TDI
  // As pulled from the input Isis cube, the values are in CPMM order, so
  // convert them to CCD order
  PvlKeyword ccdFlag("MRO:CCD_FLAG");
  PvlKeyword &cpmmFlag = origLabel.findObject("OriginalLabelObject").
                         findGroup("INSTRUMENT_SETTING_PARAMETERS").
                         findKeyword("MRO:POWERED_CPMM_FLAG");
  PvlKeyword ccdBin("MRO:BINNING");
  PvlKeyword &cpmmBin = icube2->label()->findObject("IsisCube").
                        findGroup("Mosaic")["cpmmSummingFlag"];
  PvlKeyword ccdTdi("MRO:TDI");
  PvlKeyword &cpmmTdi = icube2->label()->findObject("IsisCube").
                        findGroup("Mosaic")["cpmmTdiFlag"];
  PvlKeyword ccdSpecial("MRO:SPECIAL_PROCESSING_FLAG");
  PvlKeyword &cpmmSpecial = icube2->label()->findObject("IsisCube").
                            findGroup("Mosaic")["SpecialProcessingFlag"];
  for (int ccd = 0; ccd < 14; ++ccd) {
    const unsigned int cpmmByCcd[] = {0, 1, 2, 3, 5, 8, 10,
                                      11, 12, 13, 6, 7, 4, 9};
    ccdFlag.addValue(cpmmFlag[cpmmByCcd[ccd]]);
    ccdBin.addValue(cpmmBin[cpmmByCcd[ccd]] != "Null" ? cpmmBin[cpmmByCcd[ccd]] : "-9998");
    ccdTdi.addValue(cpmmTdi[cpmmByCcd[ccd]] != "Null" ? cpmmTdi[cpmmByCcd[ccd]] : "-9998");
    IString tmp = cpmmSpecial[cpmmByCcd[ccd]];
    tmp.Trim("\"");
    ccdSpecial.addValue(tmp.ToQt());
  }

  if (!pdsLabel.hasGroup("INSTRUMENT_SETTING_PARAMETERS")) {
    pdsLabel.addGroup(PvlGroup("INSTRUMENT_SETTING_PARAMETERS"));
  }
  pdsLabel.findGroup("INSTRUMENT_SETTING_PARAMETERS") += ccdFlag;
  pdsLabel.findGroup("INSTRUMENT_SETTING_PARAMETERS") += ccdBin;
  pdsLabel.findGroup("INSTRUMENT_SETTING_PARAMETERS") += ccdTdi;
  pdsLabel.findGroup("INSTRUMENT_SETTING_PARAMETERS") += ccdSpecial;

  // Add/modify projection info if there is a projection
  if (pdsLabel.hasObject("IMAGE_MAP_PROJECTION")) {
    PvlObject &mapObject = pdsLabel.findObject("IMAGE_MAP_PROJECTION");
    mapObject += PvlKeyword("^DATA_SET_MAP_PROJECTION", "DSMAP.CAT");

    // Add the HiRISE comment to the CENTER_LATITUDE keyword
    PvlKeyword &clat = mapObject["CENTER_LATITUDE"];
    clat.addComment("/* NOTE:  CENTER_LATITUDE and CENTER_LONGITUDE describe the location  */");
    clat.addComment("/* of the center of projection, which is not necessarily equal to the */");
    clat.addComment("/* location of the center point of the image.                         */");

    if (mapObject.hasKeyword("CENTER_LATITUDE")) {
      PvlKeyword &centerLat = mapObject["CENTER_LATITUDE"];
      // if (centerLat[0] == "N/A") centerLat = -9998;
      if (centerLat[0] == "N/A") mapObject.deleteKeyword("CENTER_LATITUDE");
    }
    if (mapObject.hasKeyword("CENTER_LONGITUDE")) {
      PvlKeyword &centerLon = mapObject["CENTER_LONGITUDE"];
      // if (centerLon[0] == "N/A") centerLon = -9998;
      if (centerLon[0] == "N/A") mapObject.deleteKeyword("CENTER_LONGITUDE");
    }
    if (mapObject.hasKeyword("REFERENCE_LATITUDE")) {
      PvlKeyword &refLat = mapObject["REFERENCE_LATITUDE"];
      // if (refLat[0] == "N/A") refLat = -9998;
      if (refLat[0] == "N/A") mapObject.deleteKeyword("REFERENCE_LATITUDE");
    }
    if (mapObject.hasKeyword("REFERENCE_LONGITUE")) {
      PvlKeyword &refLon = mapObject["REFERENCE_LONGITUDE"];
      // if (refLon[0] == "N/A") refLon = -9998;
      if (refLon[0] == "N/A") mapObject.deleteKeyword("REFERENCE_LONGITUDE");
    }
    if (mapObject.hasKeyword("FIRST_STANDARD_PARALLEL")) {
      PvlKeyword &firstSP = mapObject["FIRST_STANDARD_PARALLEL"];
      // if (firstSP[0] == "N/A") firstSP = -9998;
      if (firstSP[0] == "N/A") mapObject.deleteKeyword("FIRST_STANDARD_PARALLEL");
    }
    if (mapObject.hasKeyword("SECOND_STANDARD_PARALLEL")) {
      PvlKeyword &secondSP = mapObject["SECOND_STANDARD_PARALLEL"];
      // if (secondSP[0] == "N/A") secondSP = -9998;
      if (secondSP[0] == "N/A") mapObject.deleteKeyword("SECOND_STANDARD_PARALLEL");
    }

    // For Equirectangular ONLY
    // Modify the radii in the pds label to use the radius at the center latitude
    // instead of the target radii from NAIF
    if (mapObject["MAP_PROJECTION_TYPE"][0] == "EQUIRECTANGULAR") {
      TProjection *proj = (TProjection *) ProjectionFactory::CreateFromCube(*icube2);
      PvlGroup &mapping = icube2->label()->findGroup("MAPPING", Pvl::Traverse);
      double radius = proj->LocalRadius((double)mapping["CenterLatitude"]) / 1000.0;
      mapObject["A_AXIS_RADIUS"].setValue(toString(radius), "KM");
      mapObject["B_AXIS_RADIUS"].setValue(toString(radius), "KM");
      mapObject["C_AXIS_RADIUS"].setValue(toString(radius), "KM");
    }

    projName = mapObject["MAP_PROJECTION_TYPE"][0];
  }

  // Calculate the min/max per band keywords
  // These come from the input real DN and are converted to the PDS file DN
  // The input to output mapping is opposite from the one above
  double slope = (p.GetOutputMaximum() - p.GetOutputMinimum()) / (maxmax - minmin);
  double intercept = p.GetOutputMaximum() - slope * maxmax;
  PvlKeyword minimum("MRO:MINIMUM_STRETCH", toString(slope * g_min[0] + intercept));
  PvlKeyword maximum("MRO:MAXIMUM_STRETCH", toString(slope * g_max[0] + intercept));
  for (int band = 1; band < icube2->bandCount(); ++band) {
    minimum += toString(slope * g_min[band] + intercept);
    maximum += toString(slope * g_max[band] + intercept);
  }

  if (enctype.Equal("jp2")) {
    // Add keywords to the PDS JP2 IMAGE object
    PvlObject &imagejp2 = pdsLabel.findObject("UNCOMPRESSED_FILE").findObject("IMAGE");

    // Add the HiRISE specific description of the IMAGE object
    imagejp2 += PvlKeyword("DESCRIPTION", "HiRISE projected and mosaicked product");

    // Add the SCALLING_FACTOR and OFFSET keywords
    imagejp2.addKeyword(PvlKeyword("SCALING_FACTOR", toString(slope)), Pvl::Replace);
    imagejp2.addKeyword(PvlKeyword("OFFSET", toString(intercept)), Pvl::Replace);

    // Reformat some keyword units in the image object
    // This is lame, but PDS units are difficult to work with, so for now???
    PvlKeyword &oldFilterNamejp2 = imagejp2["FILTER_NAME"];
    PvlKeyword newFilterName("FILTER_NAME");
    for (int val = 0; val < oldFilterNamejp2.size(); ++val) {
      QString  filtname(oldFilterNamejp2[val].toUpper());
      if (filtname == "BLUEGREEN") filtname = "BLUE-GREEN";
      else if (filtname == "NEARINFRARED") filtname = "NEAR-INFRARED";
      newFilterName.addValue(filtname);
    }
    imagejp2.addKeyword(newFilterName, Pvl::Replace);

    PvlKeyword &oldCenterjp2 = imagejp2["CENTER_FILTER_WAVELENGTH"];
    PvlKeyword newCenter("CENTER_FILTER_WAVELENGTH");
    for (int val = 0; val < oldCenterjp2.size(); ++val) {
      if (((IString)(oldCenterjp2.unit(val))).UpCase() == "NANOMETERS") {
        newCenter.addValue(oldCenterjp2[val], "NM");
      }
      else {
        newCenter.addValue(oldCenterjp2[val], oldCenterjp2.unit(val));
      }
    }
    imagejp2.addKeyword(newCenter, Pvl::Replace);

    PvlKeyword &oldBandWidthjp2 = imagejp2["BAND_WIDTH"];
    PvlKeyword newBandWidth("BAND_WIDTH");
    for (int val = 0; val < oldBandWidthjp2.size(); ++val) {
      if (((IString)(oldBandWidthjp2.unit(val))).UpCase() == "NANOMETERS") {
        newBandWidth.addValue(oldBandWidthjp2[val], "nm");
      }
      else {
        newBandWidth.addValue(oldBandWidthjp2[val], oldBandWidthjp2.unit(val));
      }
    }
    imagejp2.addKeyword(newBandWidth, Pvl::Replace);

    // Add the min/max per band keywords
    imagejp2 += minimum;
    imagejp2 += maximum;

    // Modify the default SAMPLE_BIT_MASK keyword placed there by the
    // ProcessExportPds
    if (nbits != 8 && nbits != 16) {
      imagejp2.addKeyword(PvlKeyword("SAMPLE_BIT_MASK",
                                     toString((int)pow(2.0, (double)ui.GetInteger("BITS")) - 1)),
                          Pvl::Replace);
    }
  }
  else {
    // Add keywords to the PDS IMAGE object
    PvlObject &image = pdsLabel.findObject("IMAGE");

    // Add the HiRISE specific description of the IMAGE object
    image += PvlKeyword("DESCRIPTION", "HiRISE projected and mosaicked product");

    /**
     *  Calculate the SCALING_FACTOR and OFFSET keywords
     *  Set these so the unsigned 16bit PDS disk values can be converted back
     *  to the correct values Isis had
     *  These keywords are used to map stored/disk values to the correct values so,
     *  the input(x axis) values are the unsigned Xbit values from the PDS file
     */
    // ??? unneccessary calculation - this is done by ProcessExportPds class.
    double slope = (maxmax - minmin) / (p.GetOutputMaximum() - p.GetOutputMinimum()); 
    double intercept = maxmax - slope * p.GetOutputMaximum();
    image.addKeyword(PvlKeyword("SCALING_FACTOR", toString(slope)), Pvl::Replace);
    image.addKeyword(PvlKeyword("OFFSET", toString(intercept)), Pvl::Replace);

    // Reformat some keyword units in the image object
    // This is lame, but PDS units are difficult to work with, so for now
    PvlKeyword &oldFilterName = image["FILTER_NAME"];
    PvlKeyword newFilterName("FILTER_NAME");
    for (int val = 0; val < oldFilterName.size(); ++val) {
      QString  filtname(oldFilterName[val].toUpper());
      if (filtname == "BLUEGREEN") filtname = "BLUE-GREEN";
      else if (filtname == "NEARINFRARED") filtname = "NEAR-INFRARED";
      newFilterName.addValue(filtname);
    }
    image.addKeyword(newFilterName, Pvl::Replace);

    PvlKeyword &oldCenter = image["CENTER_FILTER_WAVELENGTH"];
    PvlKeyword newCenter("CENTER_FILTER_WAVELENGTH");
    for (int val = 0; val < oldCenter.size(); ++val) {
      if (((IString)(oldCenter.unit(val))).UpCase() == "NANOMETERS") {
        newCenter.addValue(oldCenter[val], "NM");
      }
      else {
        newCenter.addValue(oldCenter[val], oldCenter.unit(val));
      }
    }
    image.addKeyword(newCenter, Pvl::Replace);

    PvlKeyword &oldBandWidth = image["BAND_WIDTH"];
    PvlKeyword newBandWidth("BAND_WIDTH");
    for (int val = 0; val < oldBandWidth.size(); ++val) {
      if (((IString)(oldBandWidth.unit(val))).UpCase() == "NANOMETERS") {
        newBandWidth.addValue(oldBandWidth[val], "NM");
      }
      else {
        newBandWidth.addValue(oldBandWidth[val], oldBandWidth.unit(val));
      }
    }
    image.addKeyword(newBandWidth, Pvl::Replace);

    // Add the min/max per band keywords
    image += minimum;
    image += maximum;

    // Modify the default SAMPLE_BIT_MASK keyword placed there by the
    // ProcessExportPds
    if (nbits != 8 && nbits != 16) {
      image.addKeyword(PvlKeyword("SAMPLE_BIT_MASK",
                                  toString((int)pow(2.0, (double)ui.GetInteger("BITS")) - 1)),
                       Pvl::Replace);
    }
  }

  // Modify the units in the viewing_parameters group
//  if (pdsLabel.hasGroup("VIEWING_PARAMETERS")) {
//    PvlGroup &viewGroup = pdsLabel.findGroup("VIEWING_PARAMETERS");

//    PvlKeyword &incidence = viewGroup["INCIDENCE_ANGLE"];
//    IString tstr = incidence.unit();
//    if (tstr.UpCase() == "DEG") incidence.setValue((QString)incidence, "deg");

//    PvlKeyword &emission = viewGroup["EMISSION_ANGLE"];
//    tstr = emission.unit();
//    if (tstr.UpCase() == "DEG") emission.setValue((QString)emission, "deg");

//    PvlKeyword &phase = viewGroup["PHASE_ANGLE"];
//    tstr = phase.unit();
//    if (tstr.UpCase() == "DEG") phase.setValue((QString)phase, "deg");

//    PvlKeyword &solarLon = viewGroup["SOLAR_LONGITUDE"];
//    tstr = solarLon.unit();   q
//    if (tstr.UpCase() == "DEG") solarLon.setValue((QString)solarLon, "deg");

//    PvlKeyword &localTime = viewGroup["LOCAL_TIME"];
//    tstr = localTime.unit();
//    if (tstr.UpCase() == "LOCALDAY/24") localTime.setValue((QString)localTime, "local day/24");
//  }

  // Add a keyword type (i.e., QString, bool, int...) file to the PDS label Pvl
  PvlFormat *formatter = pdsLabel.format();
  formatter->add("$mro/translations/hirisePdsRdrExtras.typ");

  // Add an output format template (group, object, & keyword output order) to
  // the PDS PVL
  if (projName == "EQUIRECTANGULAR") {
    if (enctype.Equal("jp2")) {
      pdsLabel.setFormatTemplate("$mro/templates/labels/hirisePdsRdrEquiJP2.pft");
    }
    else {
      pdsLabel.setFormatTemplate("$mro/templates/labels/hirisePdsRdrEqui.pft");
    }
  }
  else {
    if (enctype.Equal("jp2")) {
      pdsLabel.setFormatTemplate("$mro/templates/labels/hirisePdsRdrPolarJP2.pft");
    }
    else {
      pdsLabel.setFormatTemplate("$mro/templates/labels/hirisePdsRdrPolar.pft");
    }
  }

  // Open the output PDS file and dump the label and cube data
  if (enctype.Equal("jp2")) {
    p.OutputDetachedLabel();
    g_jp2Encoder = new JP2Encoder(ui.GetFileName("TO"), icube2->sampleCount(),
                                 icube2->lineCount(), icube2->bandCount(), g_oType);
    g_jp2Encoder->OpenFile();
    g_jp2ns = icube2->sampleCount();
    g_jp2nb = icube2->bandCount();
    g_jp2band = 0;
    p.StartProcess(writeJP2Image);
    p.EndProcess();
    delete g_jp2Encoder;
    for (int i = 0; i < icube2->bandCount(); i++) {
      delete [] g_jp2buf[i];
    }
  }
  else {
    FileName outFile(ui.GetFileName("TO"));
    ofstream oCube(outFile.expanded().toAscii().data());
    p.OutputLabel(oCube);
    p.StartProcess(oCube);
    oCube.close();
    p.EndProcess();
  }

  delete [] g_min;
  delete [] g_max;
}
예제 #13
0
int testClass(const String& className, const int& attempt)
{
  Array<CIMObjectPath> refs;

  cout << endl << "+++++ Testing Class " << className << " +++++" << endl;

  // =======================================================================
  // enumerateInstanceNames
  // =======================================================================

  cout << "+++++ enumerateInstanceNames(" << className << "): ";
  try
  {
    refs = c.enumerateInstanceNames(NAMESPACE,className);
  }
  catch (Exception& e)
  {
    cout << endl;
    errorExit(e);
  }

  cout << refs.size() << " instances" << endl;

  // There must be at least 5 processes or something's wrong
  if (refs.size() < 5)
  {
    cout << "+++++ Error: too few instances returned" << endl;
    return 1;
  }

  // =======================================================================
  // getInstance
  // =======================================================================

  // -------------------- First do normal getInstance() --------------------

  // pick the middle instance of the bunch in the first attempt, or 
  // 1/4th or 1/8th of the list in second and third attempts respectively.
  
  Uint32 i = (refs.size()-1) 
      >> (attempt + 1);  // This is a shift right, not streamio!
  
  CIMObjectPath ref = refs[i];
  CIMInstance inst;
  cout << "+++++ getInstance " << i << endl;
  try
  {
    inst = c.getInstance(NAMESPACE,ref);
  }
  catch (Exception& e)
  {
    errorExit(e);
  }

  if (processTestVerbose)
  {
    // Display keys
    Array<CIMKeyBinding> keys = ref.getKeyBindings();
    cout << "  Keys:" << endl;
    for (i=0; i<keys.size(); i++)
      cout << "    " << keys[i].getName().getString() << " = " <<
          keys[i].getValue() << endl;
  }

  // check returned property values

  // first get the PID and load a process object
  String handle;
  inst.getProperty(inst.findProperty("handle")).getValue().get(handle);
  Process p;
  // error if can't get the process
  if (!p.findProcess(handle))
  {
    cout << "+++++ Error: can't find process corresponding to instance" << endl;
    return 1;
  }

  if (processTestVerbose) cout << "  Properties:" << endl;

  String sa, sb;
  Array<String> asa, asb;
  Uint16 i16a, i16b;
  Uint32 i32a, i32b;
  Uint64 i64a, i64b;
  CIMDateTime da, db;

  // For each property, get it from the just-loaded process
  // object and compare with what was returned by getInstance()

  // Caption and Description are common to all classes
  if (p.getCaption(sa))
  {
    if (processTestVerbose) cout << "    Caption" << endl;
    inst.getProperty(inst.findProperty("Caption")).getValue().get(sb);
    if (sa != sb)
    {
      cout << "+++++ Error: property mismatch: Caption" << endl;
      return 1;
    }
  }

  if (p.getDescription(sa))
  {
    if (processTestVerbose) cout << "    Description" << endl;
    inst.getProperty(inst.findProperty("Description")).getValue().get(sb);
    if (sa != sb)
    {
      cout << "+++++ Error: property mismatch: Description" << endl;
      return 1;
    }
  }

  // The rest of the properties to check depend on the
  // class we are testing

  // ===================== UnixProcess instances =========================

  if (String::equalNoCase(className,"CIM_Process") ||
      String::equalNoCase(className,"PG_UnixProcess"))
  {
    if (p.getInstallDate(da))
    {
      if (processTestVerbose) cout << "    InstallDate" << endl;
      inst.getProperty(inst.findProperty("InstallDate")).getValue().get(db);
      if (da != db)
      {
        cout << "+++++ Error: property mismatch: InstallDate" << endl;
        return 1;
      }
    }

    if (p.getStatus(sa))
    {
      if (processTestVerbose) cout << "    Status" << endl;
      inst.getProperty(inst.findProperty("Status")).getValue().get(sb);
      if (sa != sb)
      {
        cout << "+++++ Error: property mismatch: Status" << endl;
        return 1;
      }
    }

    if (p.getName(sa))
    {
      if (processTestVerbose) cout << "    Name" << endl;
      inst.getProperty(inst.findProperty("Name")).getValue().get(sb);
      if (sa != sb)
      {
        cout << "+++++ Error: property mismatch: Name" << endl;
        return 1;
      }
    }

    if (p.getPriority(i32a))
    {
      if (processTestVerbose) cout << "    Priority" << endl;
      inst.getProperty(inst.findProperty("Priority")).getValue().get(i32b);
#ifdef PEGASUS_OS_HPUX
      // Empirical evidence has shown that the priority of a process may
      // change by as much as 24 between the times it is retrieved by the
      // provider and by the test client.
      if (abs((int)i32a - (int)i32b) > 24)
#elif defined (PEGASUS_OS_LINUX)
      // On RHEL4 U2 systems, priority may change by 1.
      if (abs((int)i32a - (int)i32b) > 1)
#else
      if (i32a != i32b)
#endif
      {
        cout << "+++++ Error: property mismatch: Priority" << endl;
        cout << "Process handle = " << handle << endl;
        if (p.getDescription(sa))
        {
            cout << "Process description = " << sa << endl;
        }
        cout << "Priority expected = " << i32a << ", received = " << i32b <<
            endl;
        return 1;
      }
    }

    if (p.getExecutionState(i16a))
    {
      if (processTestVerbose) cout << "    ExecutionState" << endl;
      inst.getProperty(
          inst.findProperty("ExecutionState")).getValue().get(i16b);
      if (i16a != i16b)
      {
        cout << "+++++ Error: property mismatch: ExecutionState" << endl;
        return 1;
      }
    }

    if (p.getOtherExecutionDescription(sa))
    {
      if (processTestVerbose) cout << "    OtherExecutionDescription" << endl;
      CIMValue oedVal = inst.getProperty
          (inst.findProperty("OtherExecutionDescription")).getValue();
      if (!oedVal.isNull())
          oedVal.get(sb);
      else
         sb = String::EMPTY;
      if (sa != sb)
      {
        cout << "+++++ Error: property mismatch: OtherExecutionDescription" <<
            endl;
        return 1;
      }
    }

    if (p.getCreationDate(da))
    {
      if (processTestVerbose) cout << "    CreationDate" << endl;
      inst.getProperty(inst.findProperty("CreationDate")).getValue().get(db);
      if (da != db)
      {
        cout << "+++++ Error: property mismatch: CreationDate" << endl;
        return 1;
      }
    }

    if (p.getTerminationDate(da))
    {
      if (processTestVerbose) cout << "    TerminationDate" << endl;
      inst.getProperty(inst.findProperty("TerminationDate")).getValue().get(db);
      if (da != db)
      {
        cout << "+++++ Error: property mismatch: TerminationDate" << endl;
        return 1;
      }
    }

    if (p.getKernelModeTime(i64a))
    {
      if (processTestVerbose) cout << "    KernelModeTime" << endl;
      inst.getProperty(
          inst.findProperty("KernelModeTime")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: KernelModeTime" << endl;
        return 1;
      }
    }

    if (p.getUserModeTime(i64a))
    {
      if (processTestVerbose) cout << "    UserModeTime" << endl;
      inst.getProperty(inst.findProperty("UserModeTime")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: UserModeTime" << endl;
        return 1;
      }
    }

    if (p.getWorkingSetSize(i64a))
    {
      if (processTestVerbose) cout << "    WorkingSetSize" << endl;
      inst.getProperty(
          inst.findProperty("WorkingSetSize")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: WorkingSetSize" << endl;
        return 1;
      }
    }

    if (p.getParentProcessID(sa))
    {
      if (processTestVerbose) cout << "    ParentProcessID" << endl;
      inst.getProperty(inst.findProperty("ParentProcessID")).getValue().get(sb);
      if (sa != sb)
      {
        cout << "+++++ Error: property mismatch: ParentProcessID" << endl;
        return 1;
      }
    }

    if (p.getRealUserID(i64a))
    {
      if (processTestVerbose) cout << "    RealUserID" << endl;
      inst.getProperty(inst.findProperty("RealUserID")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: RealUserID" << endl;
        return 1;
      }
    }

    if (p.getProcessGroupID(i64a))
    {
      if (processTestVerbose) cout << "    ProcessGroupID" << endl;
      inst.getProperty(
          inst.findProperty("ProcessGroupID")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: ProcessGroupID" << endl;
        return 1;
      }
    }

    if (p.getProcessSessionID(i64a))
    {
      if (processTestVerbose) cout << "    ProcessSessionID" << endl;
      inst.getProperty(
          inst.findProperty("ProcessSessionID")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: ProcessSessionID" << endl;
        return 1;
      }
    }

    if (p.getProcessTTY(sa))
    {
      if (processTestVerbose) cout << "    ProcessTTY" << endl;
      inst.getProperty(inst.findProperty("ProcessTTY")).getValue().get(sb);
      if (sa != sb)
      {
        cout << "+++++ Error: property mismatch: ProcessTTY" << endl;
        return 1;
      }
    }

    if (p.getModulePath(sa))
    {
      if (processTestVerbose) cout << "    ModulePath" << endl;
      inst.getProperty(inst.findProperty("ModulePath")).getValue().get(sb);
      if (sa != sb)
      {
        cout << "+++++ Error: property mismatch: ModulePath" << endl;
        return 1;
      }
    }

    if (p.getParameters(asa))
    {
      if (processTestVerbose) cout << "    Parameters" << endl;
      inst.getProperty(inst.findProperty("Parameters")).getValue().get(asb);
      if (asa != asb)
      {
        cout << "+++++ Error: property mismatch: Parameters" << endl;
        return 1;
      }
    }

    if (p.getProcessNiceValue(i32a))
    {
      if (processTestVerbose) cout << "    ProcessNiceValue" << endl;
      inst.getProperty(
          inst.findProperty("ProcessNiceValue")).getValue().get(i32b);
      if (i32a != i32b)
      {
        cout << "+++++ Error: property mismatch: ProcessNiceValue" << endl;
        return 1;
      }
    }

    if (p.getProcessWaitingForEvent(sa))
    {
      if (processTestVerbose) cout << "    ProcessWaitingForEvent" << endl;
      inst.getProperty(
          inst.findProperty("ProcessWaitingForEvent")).getValue().get(sb);
      if (sa != sb)
      {
        cout << "+++++ Error: property mismatch: ProcessWaitingForEvent" <<
            endl;
        return 1;
      }
    }
    cout << "+++++ property values ok" << endl;
  }

  // ========== UnixProcessStatisticalInformation instances ===============

  else if (String::equalNoCase(
               className,"PG_UnixProcessStatisticalInformation"))
  {
    if (p.getCPUTime(i32a))
    {
      if (processTestVerbose) cout << "    CPUTime" << endl;
      inst.getProperty(inst.findProperty("CPUTime")).getValue().get(i32b);
      if (i32a != i32b)
      {
        cout << "+++++ Error: property mismatch: CPUTime" << endl;
        cout << "Process handle = " << handle << endl;
        if (p.getDescription(sa))
        {
            cout << "Process description = " << sa << endl;
        }
        cout << "CPUTime expected = " << i32a << ", received = " << i32b <<
            endl;
        return 1;
      }
    }

    if (p.getRealText(i64a))
    {
      if (processTestVerbose) cout << "    RealText" << endl;
      inst.getProperty(inst.findProperty("RealText")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: RealText" << endl;
        return 1;
      }
    }

    if (p.getRealData(i64a))
    {
      if (processTestVerbose) cout << "    RealData" << endl;
      inst.getProperty(inst.findProperty("RealData")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: RealData" << endl;
        return 1;
      }
    }

    if (p.getRealStack(i64a))
    {
      if (processTestVerbose) cout << "    RealStack" << endl;
      inst.getProperty(inst.findProperty("RealStack")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: RealStack" << endl;
        return 1;
      }
    }

    if (p.getVirtualText(i64a))
    {
      if (processTestVerbose) cout << "    VirtualText" << endl;
      inst.getProperty(inst.findProperty("VirtualText")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: VirtualText" << endl;
        return 1;
      }
    }

    if (p.getVirtualData(i64a))
    {
      if (processTestVerbose) cout << "    VirtualData" << endl;
      inst.getProperty(inst.findProperty("VirtualData")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: VirtualData" << endl;
        return 1;
      }
    }

    if (p.getVirtualStack(i64a))
    {
      if (processTestVerbose) cout << "    VirtualStack" << endl;
      inst.getProperty(inst.findProperty("VirtualStack")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: VirtualStack" << endl;
        return 1;
      }
    }

    if (p.getVirtualMemoryMappedFileSize(i64a))
    {
      if (processTestVerbose) cout << "    VirtualMemoryMappedFileSize" << endl;
      inst.getProperty(inst.findProperty(
          "VirtualMemoryMappedFileSize")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: VirtualMemoryMappedFileSize"
             << endl;
        return 1;
      }
    }

    if (p.getVirtualSharedMemory(i64a))
    {
      if (processTestVerbose) cout << "    VirtualSharedMemory" << endl;
      inst.getProperty(
          inst.findProperty("VirtualSharedMemory")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: VirtualSharedMemory" << endl;
        return 1;
      }
    }

    if (p.getCpuTimeDeadChildren(i64a))
    {
      if (processTestVerbose) cout << "    CpuTimeDeadChildren" << endl;
      inst.getProperty(
          inst.findProperty("CpuTimeDeadChildren")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: CpuTimeDeadChildren" << endl;
        return 1;
      }
    }

    if (p.getSystemTimeDeadChildren(i64a))
    {
      if (processTestVerbose) cout << "    SystemTimeDeadChildren" << endl;
      inst.getProperty(
          inst.findProperty("SystemTimeDeadChildren")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: SystemTimeDeadChildren" <<
            endl;
        return 1;
      }
    }

    if (p.getRealSpace(i64a))
    {
      if (processTestVerbose) cout << "    RealSpace" << endl;
      inst.getProperty(inst.findProperty("RealSpace")).getValue().get(i64b);
      if (i64a != i64b)
      {
        cout << "+++++ Error: property mismatch: RealSpace" << endl;
        return 1;
      }
    }

    cout << "+++++ property values ok" << endl;
  }

  else
  {
    cout << "+++++ Error: class " << className << " not recognized" << endl;
    return 1;
  }

  // ------------------ do getInstance() with bad key ----------------------

  Array<CIMKeyBinding> kb = ref.getKeyBindings();
  // mess up first key name
  kb[0].setName("foobar");
  ref.setKeyBindings(kb);

  int status = 0;

  cout << "+++++ getInstance with bad key" << endl;
  try
  {
    inst = c.getInstance(NAMESPACE,ref);
  }
  catch (CIMException& e)
  {
    if (e.getCode() == CIM_ERR_INVALID_PARAMETER) status = 1;
  }
  catch (Exception&)
  {
    // any other exception is a failure; leave status alone
  }
  if (status == 0)
  {
    cout << "+++++ Error: bad instance name not rejected" << endl;
    return 1;
  }

  // =======================================================================
  // createInstance
  // =======================================================================

  CIMObjectPath ref2;
  cout << "+++++ createInstance" << endl;
  status = 0;
  try
  {
    ref2 = c.createInstance(NAMESPACE,inst);
  }
  catch (CIMException& e)
  {
    if (e.getCode() == CIM_ERR_NOT_SUPPORTED) status = 1;
  }
  catch (Exception&)
  {
    // any other Exception is a problem; leave status alone
  }
  if (status == 0)
  {
    cout << "+++++ Error: createInstance didn't throw exception" << endl;
    return 1;
  }

  // =======================================================================
  // deleteInstance
  // =======================================================================

  cout << "+++++ deleteInstance" << endl;
  status = 0;
  try
  {
    c.deleteInstance(NAMESPACE,ref);
  }
  catch (CIMException& e)
  {
    if (e.getCode() == CIM_ERR_NOT_SUPPORTED) status = 1;
  }
  catch (Exception&)
  {
    // any other Exception is a problem; leave status alone
  }
  if (status == 0)
  {
    cout << "+++++ Error: deleteInstance didn't throw exception" << endl;
    return 1;
  }

  // =======================================================================
  // enumerateInstances
  // =======================================================================

  cout << "+++++ enumerateInstances(" << className << ")" << endl;

  Array<CIMInstance> ia;
  try
  {
    ia = c.enumerateInstances(NAMESPACE,className);
  }
  catch (Exception& e)
  {
    errorExit(e);
  }

  // There should be several instances
  if (ia.size() < 5)
  {
    cout << "+++++ Error: enumerateInstances on " << className <<
        " returned too few instances" << endl;
    return 1;
  }

#ifndef PEGASUS_TEST_VALGRIND
  // For UnixProcess, we should be able to find this test process
  // and the cimserver
  if (String::equalNoCase(className,"CIM_Process") ||
      String::equalNoCase(className,"PG_UnixProcess"))
  {
    status = 0;
    for (i=0; i<ia.size(); i++)
    {
      Array<String> cmd;
      ia[i].getProperty(ia[i].findProperty("Parameters")).getValue().get(cmd);
      if (cmd[0] == "cimserver")
      {
        status++;
        if (processTestVerbose) cout << "    cimserver" << endl;
      }
      if (cmd[0] == "TestClientProcessProvider")
      {
        status++;
        if (processTestVerbose) cout << "    ProcessProviderTestClient" << endl;
      }
    }
    if (status < 2)
    {
      cout << "Error: couldn't find cimserver or test client process!" << endl;
      return 1;
    }
  }
#endif

  // =======================================================================
  // modifyInstance
  // =======================================================================

  // We do modifyInstance after enumerateInstances, because
  // modifyInstance requires a CIMInstance argument, which
  // is conveniently what was returned by enumerateInstances

  CIMInstance ni = ia[(ia.size()-1) >> 1]; // pick the middle one

  cout << "+++++ modifyInstance" << endl;
  status = 0;
  try
  {
    c.modifyInstance(NAMESPACE,ni);
  }
  catch (CIMException& e)
  {
    if (e.getCode() == CIM_ERR_NOT_SUPPORTED) status = 1;
  }
  catch (Exception&)
  {
    // any other Exception is a problem; leave status alone
  }
  if (status == 0)
  {
    cout << "+++++ Error: modifyInstance didn't throw exception" << endl;
    return 1;
  }

  // =======================================================================
  // Tests completed
  // =======================================================================

  return 0;
}
예제 #14
0
int sys_ppoll(struct pollfd* user_fds, size_t nfds,
              const struct timespec* user_timeout_ts,
              const sigset_t* user_sigmask)
{
	ioctx_t ctx; SetupKernelIOCtx(&ctx);

	struct timespec timeout_ts;
	if ( !FetchTimespec(&timeout_ts, user_timeout_ts) )
		return -1;

	if ( user_sigmask )
		return errno = ENOSYS, -1;

	struct pollfd* fds = CopyFdsFromUser(user_fds, nfds);
	if ( !fds ) { return -1; }

	PollNode* nodes = new PollNode[nfds];
	if ( !nodes ) { delete[] fds; return -1; }

	Process* process = CurrentProcess();

	kthread_mutex_t wakeup_mutex = KTHREAD_MUTEX_INITIALIZER;
	kthread_cond_t wakeup_cond = KTHREAD_COND_INITIALIZER;

	kthread_mutex_lock(&wakeup_mutex);

	int ret = -1;
	bool self_woken = false;
	bool remote_woken = false;
	bool unexpected_error = false;

	Timer timer;
	struct poll_timeout pts;
	if ( timespec_le(timespec_make(0, 1), timeout_ts) )
	{
		timer.Attach(Time::GetClock(CLOCK_MONOTONIC));
		struct itimerspec its;
		its.it_interval = timespec_nul();
		its.it_value = timeout_ts;
		pts.wake_mutex = &wakeup_mutex;
		pts.wake_cond = &wakeup_cond;
		pts.woken = &remote_woken;
		timer.Set(&its, NULL, 0, poll_timeout_callback, &pts);
	}

	size_t reqs;
	for ( reqs = 0; !unexpected_error && reqs < nfds; )
	{
		PollNode* node = nodes + reqs;
		if ( fds[reqs].fd < 0 )
		{
			fds[reqs].revents = POLLNVAL;
			// TODO: Should we set POLLNVAL in node->revents too? Should this
			// system call ignore this error and keep polling, or return to
			// user-space immediately? What if conditions are already true on
			// some of the file descriptors (those we have processed so far?)?
			node->revents = 0;
			reqs++;
			continue;
		}
		Ref<Descriptor> desc = process->GetDescriptor(fds[reqs].fd);
		if ( !desc ) { self_woken = unexpected_error = true; break; }
		node->events = fds[reqs].events | POLL__ONLY_REVENTS;
		node->revents = 0;
		node->wake_mutex = &wakeup_mutex;
		node->wake_cond = &wakeup_cond;
		node->woken = &remote_woken;
		reqs++;
		// TODO: How should errors be handled?
		if ( desc->poll(&ctx, node) == 0 )
			self_woken = true;
		else if ( errno == EAGAIN )
			errno = 0;
		else
			unexpected_error = self_woken = true;
	}

	if ( timeout_ts.tv_sec == 0 && timeout_ts.tv_nsec == 0 )
		self_woken = true;

	while ( !(self_woken || remote_woken) )
	{
		if ( !kthread_cond_wait_signal(&wakeup_cond, &wakeup_mutex) )
			errno = -EINTR,
			self_woken = true;
	}

	kthread_mutex_unlock(&wakeup_mutex);

	for ( size_t i = 0; i < reqs; i++ )
		if ( 0 <= fds[i].fd )
			nodes[i].Cancel();

	if ( timespec_le(timespec_make(0, 1), timeout_ts) )
	{
		timer.Cancel();
		timer.Detach();
	}

	if ( !unexpected_error )
	{
		int num_events = 0;
		for ( size_t i = 0; i < reqs; i++ )
		{
			if ( fds[i].fd < -1 )
				continue;
			if ( (fds[i].revents = nodes[i].revents) )
				num_events++;
		}

		if ( CopyFdsToUser(user_fds, fds, nfds) )
			ret = num_events;
	}

	delete[] nodes;
	delete[] fds;
	return ret;
}
예제 #15
0
NODE_IMPLEMENTATION(DynamicPartialApplication::node, Pointer)
{
    //
    //  Never do partial application on the result of a lambda
    //  expression (its too difficult to archive). Instead do
    //  partial evaluation. The good side is that there will never
    //  be more than one level of indirection in multiple-curried
    //  lambda expressions. the bad side is that there will be
    //  more overhead upfront.
    //

    Process* p = NODE_THREAD.process();
    Context* c = p->context();
    FunctionObject* f = NODE_ARG_OBJECT(1, FunctionObject);
    bool apply = f->function()->isLambda();

    try
    {
        if (apply)
        {
            typedef PartialApplicator Generator;
            Generator::ArgumentVector args(f->function()->numArgs() +
                                           f->function()->numFreeVariables());
            Generator::ArgumentMask   mask(args.size());

            for (int i=0; i < args.size(); i++)
            {
                mask[i] = NODE_THIS.argNode(i+2)->symbol() != c->noop();
                if (mask[i])
                {
                    args[i] = NODE_ANY_TYPE_ARG(i+2);
                }
            }

            Generator evaluator(f->function(), p, &NODE_THREAD, args, mask);

            const FunctionType* rt = evaluator.result()->type();
            assert(rt == NODE_THIS.argNode(0)->type());
            FunctionObject* o = new FunctionObject(rt);
            o->setDependent(f);
            o->setFunction(evaluator.result());
            NODE_RETURN(Pointer(o));
        }
        else
        {
            typedef FunctionSpecializer Generator;
            Generator::ArgumentVector args(f->function()->numArgs() +
                                           f->function()->numFreeVariables());
            Generator::ArgumentMask   mask(args.size());

            for (int i=0; i < args.size(); i++)
            {
                mask[i] = NODE_THIS.argNode(i+2)->symbol() != c->noop();

                if (mask[i])
                {
                    args[i] = NODE_ANY_TYPE_ARG(i+2);
                }
            }

            Generator evaluator(f->function(), p, &NODE_THREAD);
            evaluator.partiallyEvaluate(args, mask);

            const FunctionType* rt = evaluator.result()->type();
            assert(rt == NODE_THIS.argNode(0)->type());
            FunctionObject* o = new FunctionObject(rt);
            o->setFunction(evaluator.result());
            NODE_RETURN(Pointer(o));
        }
    }
    catch (Exception& e)
    {
        ProgramException exc(NODE_THREAD);
        exc.message() = e.message();
        exc.message() += " during partial ";
        exc.message() += (apply ? "application" : "evaluation");
        exc.message() += " of ";
        exc.message() += f->function()->name().c_str();
        throw exc;
    }
}
예제 #16
0
void* ReceiveStateFromParticipant(void* _rcv_thread_arg) {
    ReceiveStateThreadArgument *rcv_thread_arg = (ReceiveStateThreadArgument *)_rcv_thread_arg;
    int pid = rcv_thread_arg->pid;
    int tid = rcv_thread_arg->transaction_id;
    Process *p = rcv_thread_arg->p;
    char buf[kMaxDataSize];
    int num_bytes;
    //TODO: write code to extract multiple messages

    fd_set temp_set;
    FD_ZERO(&temp_set);
    FD_SET(p->get_fd(pid), &temp_set);
    int fd_max = p->get_fd(pid);
    int rv;
    rv = select(fd_max + 1, &temp_set, NULL, NULL, (timeval*)&kTimeout);
    if (rv == -1) { //error in select
        // cout << "P" << p->get_pid() << ": ERROR in select() for P" << pid << strerror(errno)<< endl;
        rcv_thread_arg->st = PROCESSTIMEOUT;
        p->RemoveFromUpSet(pid);
    } else if (rv == 0) {   //timeout
        rcv_thread_arg->st = PROCESSTIMEOUT;
        p->RemoveFromUpSet(pid);
    } else {    // activity happened on the socket
        if ((num_bytes = recv(p->get_fd(pid), buf, kMaxDataSize - 1, 0)) == -1) {
            // cout << "P" << p->get_pid() << ": ERROR in receiving for P" << pid << endl;
            rcv_thread_arg->st = PROCESSTIMEOUT;
            p->RemoveFromUpSet(pid);
        } else if (num_bytes == 0) {     //connection closed
            // cout << "P" << p->get_pid() << ": Connection closed by P" << pid << endl;
            // if participant closes connection, it is equivalent to it crashing
            // can treat it as TIMEOUT
            // TODO: verify argument
            rcv_thread_arg->st = PROCESSTIMEOUT;
            p->RemoveFromUpSet(pid);
            //TODO: handle connection close based on different cases
        } else {
            buf[num_bytes] = '\0';
            cout << "P" << p->get_pid() << ": STATE received from P" << pid << ": " << buf <<  endl;

            string extracted_msg;
            int received_tid;
            // in this case, we don't care about the received_tid,
            // because it will surely be for the transaction under consideration
            p->ExtractMsg(string(buf), extracted_msg, received_tid);

            ProcessState msg = static_cast<ProcessState>(atoi(extracted_msg.c_str()));
            rcv_thread_arg->st = msg;
            //assumes that correct message type is sent by participant

            // if (msg==)  {    // it's a YES
            //     received_msg_type = YES;
            // } else if (extracted_msg == msg2) { // it's a NO
            //     received_msg_type = NO;
            // } else {
            //     //TODO: take actions appropriately, like check log for previous transaction decision.
            //     cout << "P" << p->get_pid() << ": Unexpected msg received from P" << pid << endl;
            //     received_msg_type = ERROR;
            // }
        }
    }
    // cout << "P" << p->get_pid() << ": Receive thread exiting for P" << pid << endl;
    return NULL;
}
예제 #17
0
Error
ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_allocation_addr, 
                                            lldb::addr_t &func_addr, 
                                            lldb::addr_t &func_end, 
                                            ExecutionContext &exe_ctx,
                                            IRForTarget::StaticDataAllocator *data_allocator,
                                            bool &evaluated_statically,
                                            lldb::ClangExpressionVariableSP &const_result,
                                            ExecutionPolicy execution_policy)
{
    func_allocation_addr = LLDB_INVALID_ADDRESS;
	func_addr = LLDB_INVALID_ADDRESS;
	func_end = LLDB_INVALID_ADDRESS;
    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    std::auto_ptr<llvm::ExecutionEngine> execution_engine;
    
    Error err;
    
    llvm::Module *module = m_code_generator->ReleaseModule();

    if (!module)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("IR doesn't contain a module");
        return err;
    }
    
    // Find the actual name of the function (it's often mangled somehow)
    
    std::string function_name;
    
    if (!FindFunctionInModule(function_name, module, m_expr.FunctionName()))
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
        return err;
    }
    else
    {
        if (log)
            log->Printf("Found function %s for %s", function_name.c_str(), m_expr.FunctionName());
    }
    
    ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL
    
    if (decl_map)
    {
        Stream *error_stream = NULL;
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
            error_stream = &target->GetDebugger().GetErrorStream();
    
        IRForTarget ir_for_target(decl_map,
                                  m_expr.NeedsVariableResolution(),
                                  execution_policy,
                                  const_result,
                                  data_allocator,
                                  error_stream,
                                  function_name.c_str());
        
        ir_for_target.runOnModule(*module);
        
        Error &interpreter_error(ir_for_target.getInterpreterError());
        
        if (execution_policy != eExecutionPolicyAlways && interpreter_error.Success())
        {
            if (const_result)
                const_result->TransferAddress();
            evaluated_statically = true;
            err.Clear();
            return err;
        }
        
        Process *process = exe_ctx.GetProcessPtr();

        if (!process || execution_policy == eExecutionPolicyNever)
        {
            err.SetErrorToGenericError();
            if (execution_policy == eExecutionPolicyAlways)
                err.SetErrorString("Execution needed to run in the target, but the target can't be run");
            else
                err.SetErrorStringWithFormat("Interpreting the expression locally failed: %s", interpreter_error.AsCString());

            return err;
        }
        
        if (execution_policy != eExecutionPolicyNever &&
            m_expr.NeedsValidation() && 
            process)
        {
            if (!process->GetDynamicCheckers())
            {                
                DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
                
                StreamString install_errors;
                
                if (!dynamic_checkers->Install(install_errors, exe_ctx))
                {
                    if (install_errors.GetString().empty())
                        err.SetErrorString ("couldn't install checkers, unknown error");
                    else
                        err.SetErrorString (install_errors.GetString().c_str());
                    
                    return err;
                }
                
                process->SetDynamicCheckers(dynamic_checkers);
                
                if (log)
                    log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
            }
            
            IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.c_str());
        
            if (!ir_dynamic_checks.runOnModule(*module))
            {
                err.SetErrorToGenericError();
                err.SetErrorString("Couldn't add dynamic checks to the expression");
                return err;
            }
        }
    }
    
    // llvm will own this pointer when llvm::ExecutionEngine::createJIT is called 
    // below so we don't need to free it.
    RecordingMemoryManager *jit_memory_manager = new RecordingMemoryManager();
    
    std::string error_string;

    if (log)
    {
        std::string s;
        raw_string_ostream oss(s);
        
        module->print(oss, NULL);
        
        oss.flush();
        
        log->Printf ("Module being sent to JIT: \n%s", s.c_str());
    }
    
    EngineBuilder builder(module);
    builder.setEngineKind(EngineKind::JIT)
        .setErrorStr(&error_string)
        .setRelocationModel(llvm::Reloc::PIC_)
        .setJITMemoryManager(jit_memory_manager)
        .setOptLevel(CodeGenOpt::Less)
        .setAllocateGVsWithCode(true)
        .setCodeModel(CodeModel::Small)
        .setUseMCJIT(true);
    execution_engine.reset(builder.create());
        
    if (!execution_engine.get())
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't JIT the function: %s", error_string.c_str());
        return err;
    }
    
    execution_engine->DisableLazyCompilation();
    
    llvm::Function *function = module->getFunction (function_name.c_str());
    
    // We don't actually need the function pointer here, this just forces it to get resolved.
    
    void *fun_ptr = execution_engine->getPointerToFunction(function);
        
    // Errors usually cause failures in the JIT, but if we're lucky we get here.
    
    if (!function)
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't find '%s' in the JITted module", function_name.c_str());
        return err;
    }
    
    if (!fun_ptr)
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("'%s' was in the JITted module but wasn't lowered", function_name.c_str());
        return err;
    }
    
    m_jitted_functions.push_back (ClangExpressionParser::JittedFunction(function_name.c_str(), (lldb::addr_t)fun_ptr));
    

    Process *process = exe_ctx.GetProcessPtr();
    if (process == NULL)
    {
        err.SetErrorToGenericError();
        err.SetErrorString("Couldn't write the JIT compiled code into the target because there is no target");
        return err;
    }
        
    jit_memory_manager->CommitAllocations(*process);
    jit_memory_manager->ReportAllocations(*execution_engine);
    jit_memory_manager->WriteData(*process);
    
    std::vector<JittedFunction>::iterator pos, end = m_jitted_functions.end();
    
    for (pos = m_jitted_functions.begin(); pos != end; pos++)
    {
        (*pos).m_remote_addr = jit_memory_manager->GetRemoteAddressForLocal ((*pos).m_local_addr);
    
        if (!(*pos).m_name.compare(function_name.c_str()))
        {
            RecordingMemoryManager::AddrRange func_range = jit_memory_manager->GetRemoteRangeForLocal((*pos).m_local_addr);
            func_end = func_range.first + func_range.second;
            func_addr = (*pos).m_remote_addr;
        }
    }
    
    if (log)
    {
        log->Printf("Code can be run in the target.");
        
        StreamString disassembly_stream;
        
        Error err = DisassembleFunction(disassembly_stream, exe_ctx, jit_memory_manager);
        
        if (!err.Success())
        {
            log->Printf("Couldn't disassemble function : %s", err.AsCString("unknown error"));
        }
        else
        {
            log->Printf("Function disassembly:\n%s", disassembly_stream.GetData());
        }
    }
    
    execution_engine.reset();
    
    err.Clear();
    return err;
}
예제 #18
0
void* NewCoordinatorMode(void * _p) {
    //TODO: send tid to ConstructVoteReq;
    Process *p = (Process *)_p;
    ofstream outf("log/newcoord" + to_string(p->get_pid()) + "," + to_string(time(NULL) % 100), fstream::app);
    outf << "New Coordinator = " << p->get_pid() << endl;

    // connect to each participant
    p->participant_state_map_.clear();
    //set participant state map but only those processes that are alive
    for (auto it = p->up_.begin(); it != p->up_.end(); it++) {
        if (*it == p->get_pid()) continue;
        if (p->ConnectToProcess(*it))
            p->participant_state_map_.insert(make_pair(*it, UNINITIALIZED));
        // else
        // cout << "P" << p->get_pid() << ": Unable to connect to P" << *it << endl;
    }
    // return NULL;
    string msg;
    p->ConstructStateReq(msg);

    p->SendStateReqToAll(msg);
    outf << "sent state req" << endl;
    p->WaitForStates();
    ProcessState my_st = p->get_my_state();

    // if(p->get_pid() == 1) return NULL;

    bool aborted = false;
    for (const auto& ps : p->participant_state_map_) {
        if (ps.second == ABORTED)
        {
            aborted = true;
            break;
        }
    }

    if (my_st == ABORTED || aborted)
    {
        if (my_st != ABORTED)
        {
            p->LogAbort();
            //only log if other process is abort.
            //if i know aborted, means already in log abort
            my_st = ABORTED;

        }

        for (const auto& ps : p->participant_state_map_) {
            p->SendAbortToProcess(ps.first);
        }
        p->set_my_state(ABORTED);
        p->RemoveThreadFromSet(pthread_self());
        return NULL;
    }

    bool committed = false;
    for (const auto& ps : p->participant_state_map_) {
        if (ps.second == COMMITTED)
        {
            committed = true;
            break;
        }
    }

    if (my_st == COMMITTED || committed)
    {
        if (my_st != COMMITTED)
        {
            p->LogCommit();
            my_st = COMMITTED;
        }
        p->SendCommitToAll();
        p->set_my_state(COMMITTED);
        p->RemoveThreadFromSet(pthread_self());
        return NULL;
    }


    bool uncert = true;
    for (const auto& ps : p->participant_state_map_) {
        if (ps.second == PROCESSTIMEOUT)continue;
        if (ps.second != UNCERTAIN)
        {
            uncert = false;
            break;
        }
    }
    if (uncert && my_st == UNCERTAIN)
    {
        outf << "sending abort" << endl;
        p->LogAbort();
        for (const auto& ps : p->participant_state_map_) {
            p->SendAbortToProcess(ps.first);
        }
        p->set_my_state(ABORTED);
        p->RemoveThreadFromSet(pthread_self());
        return NULL;
    }

    //else
    //some are commitable
    p->LogPreCommit();
    outf << "sending precommit"<< endl;
    for (const auto& ps : p->participant_state_map_) {
        p->SendPreCommitToProcess(ps.first);
    }
    p->WaitForAck();
    p->LogCommit();
    p->set_my_state(COMMITTED);
    p->SendCommitToAll();
    outf << "sent commit " << endl;
    if (my_st == ABORTED)
        p->prev_decisions_.push_back(ABORT);
    else
        p->prev_decisions_.push_back(COMMIT);

    p->RemoveThreadFromSet(pthread_self());
    return NULL;
}
예제 #19
0
파일: hist.cpp 프로젝트: assutech/isis3
void IsisMain() {
  Process p;
  Cube *icube = p.SetInputCube("FROM");

  // Setup the histogram
  UserInterface &ui = Application::GetUserInterface();
  Histogram hist(*icube,1,p.Progress());
  if (ui.WasEntered("MINIMUM")) {
    hist.SetValidRange(ui.GetDouble("MINIMUM"),ui.GetDouble("MAXIMUM"));
  }
  if (ui.WasEntered("NBINS")) {
    hist.SetBins(ui.GetInteger("NBINS"));
  }

  // Loop and accumulate histogram
  p.Progress()->SetText("Gathering Histogram");
  p.Progress()->SetMaximumSteps(icube->Lines());
  p.Progress()->CheckStatus();
  LineManager line(*icube);
  for (int i=1; i<=icube->Lines(); i++) {
    line.SetLine(i);
    icube->Read(line);
    hist.AddData(line.DoubleBuffer(),line.size());
    p.Progress()->CheckStatus();
  }

  if(!ui.IsInteractive() || ui.WasEntered("TO")) {
    // Write the results

    if (!ui.WasEntered("TO")) {
      string msg = "The [TO] parameter must be entered";
      throw iException::Message(iException::User,msg,_FILEINFO_);
    }
    string outfile = ui.GetFilename("TO");
    ofstream fout;
    fout.open (outfile.c_str());
   
    fout << "Cube:           " << ui.GetFilename("FROM") << endl;
    fout << "Band:           " << icube->Bands() << endl;
    fout << "Average:        " << hist.Average() << endl;
    fout << "Std Deviation:  " << hist.StandardDeviation() << endl;
    fout << "Variance:       " << hist.Variance() << endl;
    fout << "Median:         " << hist.Median() << endl;
    fout << "Mode:           " << hist.Mode() << endl;
    fout << "Skew:           " << hist.Skew() << endl;
    fout << "Minimum:        " << hist.Minimum() << endl;
    fout << "Maximum:        " << hist.Maximum() << endl;
    fout << endl;
    fout << "Total Pixels:    " << hist.TotalPixels() << endl;
    fout << "Valid Pixels:    " << hist.ValidPixels() << endl;
    fout << "Null Pixels:     " << hist.NullPixels() << endl;
    fout << "Lis Pixels:      " << hist.LisPixels() << endl;
    fout << "Lrs Pixels:      " << hist.LrsPixels() << endl;
    fout << "His Pixels:      " << hist.HisPixels() << endl;
    fout << "Hrs Pixels:      " << hist.HrsPixels() << endl;
   
    //  Write histogram in tabular format
    fout << endl;
    fout << endl;
    fout << "DN,Pixels,CumulativePixels,Percent,CumulativePercent" << endl;
   
    Isis::BigInt total = 0;
    double cumpct = 0.0;
   
    for (int i=0; i<hist.Bins(); i++) {
      if (hist.BinCount(i) > 0) {
        total += hist.BinCount(i);
        double pct = (double)hist.BinCount(i) / hist.ValidPixels() * 100.;
        cumpct += pct;
   
        fout << hist.BinMiddle(i) << ",";
        fout << hist.BinCount(i) << ",";
        fout << total << ",";
        fout << pct << ",";
        fout << cumpct << endl;
      }
    }
    fout.close();
  }
  // If we are in gui mode, create a histogram plot
  if (ui.IsInteractive()) {
    // Set the title for the dialog
    string title;
    if (ui.WasEntered("TITLE")) {
      title = ui.GetString("TITLE");
    }
    else {
      title = "Histogram Plot for " + Filename(ui.GetAsString("FROM")).Name();
    }

    // Create the QHistogram, set the title & load the Isis::Histogram into it

    Qisis::HistogramToolWindow *plot = new Qisis::HistogramToolWindow(title.c_str(), ui.TheGui());

    // Set the xaxis title if they entered one
    if (ui.WasEntered("XAXIS")) {
      string xaxis(ui.GetString("XAXIS"));
      plot->setAxisLabel(QwtPlot::xBottom,xaxis.c_str());
    }

    // Set the yLeft axis title if they entered one
    if (ui.WasEntered("Y1AXIS")) {
      string yaxis(ui.GetString("Y1AXIS"));
      plot->setAxisLabel(QwtPlot::yLeft,yaxis.c_str());
    }

    // Set the yRight axis title if they entered one
    if (ui.WasEntered("Y2AXIS")) {
      string y2axis(ui.GetString("Y2AXIS"));
      plot->setAxisLabel(QwtPlot::yRight,y2axis.c_str());
    }

    //Transfer data from histogram to the plotcurve
    std::vector<double> xarray,yarray,y2array;
    double cumpct = 0.0;
    for (int i=0; i<hist.Bins(); i++) {
      if (hist.BinCount(i) > 0) {
        xarray.push_back(hist.BinMiddle(i));
        yarray.push_back(hist.BinCount(i));

        double pct = (double)hist.BinCount(i) / hist.ValidPixels() * 100.;
        cumpct += pct;
        y2array.push_back(cumpct);
      }
    }

    Qisis::HistogramItem *histCurve = new Qisis::HistogramItem();
    histCurve->setColor(Qt::darkCyan);
    histCurve->setTitle("Frequency");

    Qisis::PlotToolCurve *cdfCurve = new Qisis::PlotToolCurve();
    cdfCurve->setStyle(QwtPlotCurve::Lines);
    cdfCurve->setTitle("Percentage");

    QPen *pen = new QPen(Qt::red);
    pen->setWidth(2);
    histCurve->setYAxis(QwtPlot::yLeft);
    cdfCurve->setYAxis(QwtPlot::yRight);
    cdfCurve->setPen(*pen);

    //These are all variables needed in the following for loop.
    //----------------------------------------------
    QwtArray<QwtDoubleInterval> intervals(xarray.size());
    QwtArray<double> values(yarray.size());
    double maxYValue = DBL_MIN;
    double minYValue = DBL_MAX;
    // --------------------------------------------- 

    for(unsigned int y = 0; y < yarray.size(); y++) {

      intervals[y] = QwtDoubleInterval(xarray[y], xarray[y] + hist.BinSize());
  
      values[y] = yarray[y];  
      if(values[y] > maxYValue) maxYValue = values[y]; 
      if(values[y] < minYValue) minYValue = values[y];
    }
    
    histCurve->setData(QwtIntervalData(intervals, values));
    cdfCurve->setData(&xarray[0],&y2array[0],xarray.size());

    plot->add(histCurve);
    plot->add(cdfCurve);
    plot->fillTable();

    plot->setScale(QwtPlot::yLeft,0,maxYValue);
    plot->setScale(QwtPlot::xBottom,hist.Minimum(),hist.Maximum());

    QLabel *label = new QLabel("  Average = " + QString::number(hist.Average()) + '\n' +
    "\n  Minimum = " + QString::number(hist.Minimum()) + '\n' +
    "\n  Maximum = " + QString::number(hist.Maximum()) + '\n' +
    "\n  Stand. Dev.= " + QString::number(hist.StandardDeviation()) + '\n' +
    "\n  Variance = " + QString::number(hist.Variance()) + '\n' +
    "\n  Median = " + QString::number(hist.Median()) + '\n' +
    "\n  Mode = " + QString::number(hist.Mode()) +'\n' +
    "\n  Skew = " + QString::number(hist.Skew()), plot);
    plot->getDockWidget()->setWidget(label);
 
    plot->showWindow();
  }
  p.EndProcess();
}
예제 #20
0
Error
ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
                                            lldb::addr_t &func_end,
                                            std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
                                            ExecutionContext &exe_ctx,
                                            bool &can_interpret,
                                            ExecutionPolicy execution_policy)
{
	func_addr = LLDB_INVALID_ADDRESS;
	func_end = LLDB_INVALID_ADDRESS;
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    Error err;

    std::unique_ptr<llvm::Module> llvm_module_ap (m_code_generator->ReleaseModule());

    if (!llvm_module_ap.get())
    {
        err.SetErrorToGenericError();
        err.SetErrorString("IR doesn't contain a module");
        return err;
    }

    // Find the actual name of the function (it's often mangled somehow)

    ConstString function_name;

    if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName()))
    {
        err.SetErrorToGenericError();
        err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
        return err;
    }
    else
    {
        if (log)
            log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
    }

    execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here
                                                 llvm_module_ap, // handed off here
                                                 function_name,
                                                 exe_ctx.GetTargetSP(),
                                                 m_compiler->getTargetOpts().Features));

    ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL

    if (decl_map)
    {
        Stream *error_stream = NULL;
        Target *target = exe_ctx.GetTargetPtr();
        if (target)
            error_stream = target->GetDebugger().GetErrorFile().get();

        IRForTarget ir_for_target(decl_map,
                                  m_expr.NeedsVariableResolution(),
                                  *execution_unit_sp,
                                  error_stream,
                                  function_name.AsCString());

        bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule());

        Error interpret_error;

        can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error);

        Process *process = exe_ctx.GetProcessPtr();

        if (!ir_can_run)
        {
            err.SetErrorString("The expression could not be prepared to run in the target");
            return err;
        }

        if (!can_interpret && execution_policy == eExecutionPolicyNever)
        {
            err.SetErrorStringWithFormat("Can't run the expression locally: %s", interpret_error.AsCString());
            return err;
        }

        if (!process && execution_policy == eExecutionPolicyAlways)
        {
            err.SetErrorString("Expression needed to run in the target, but the target can't be run");
            return err;
        }

        if (execution_policy == eExecutionPolicyAlways || !can_interpret)
        {
            if (m_expr.NeedsValidation() && process)
            {
                if (!process->GetDynamicCheckers())
                {
                    DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();

                    StreamString install_errors;

                    if (!dynamic_checkers->Install(install_errors, exe_ctx))
                    {
                        if (install_errors.GetString().empty())
                            err.SetErrorString ("couldn't install checkers, unknown error");
                        else
                            err.SetErrorString (install_errors.GetString().c_str());

                        return err;
                    }

                    process->SetDynamicCheckers(dynamic_checkers);

                    if (log)
                        log->Printf("== [ClangUserExpression::Evaluate] Finished installing dynamic checkers ==");
                }

                IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString());

                if (!ir_dynamic_checks.runOnModule(*execution_unit_sp->GetModule()))
                {
                    err.SetErrorToGenericError();
                    err.SetErrorString("Couldn't add dynamic checks to the expression");
                    return err;
                }
            }

            execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
        }
    }
    else
    {
        execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
    }

    return err;
}
예제 #21
0
void IsisMain() {

    // Use a regular Process
    Process p;

    // Get user parameters and error check
    UserInterface &ui = Application::GetUserInterface();
    QString from = ui.GetFileName("FROM");
    QString to = FileName(ui.GetFileName("TO")).expanded();
//TO DO: UNCOMMENT THIS LINE ONCE HRSC IS WORKING IN SS
//  double HRSCNadirCenterTime = ui.GetDouble("HRSC_NADIRCENTERTIME");

    // Open input cube and Make sure this is a lev1 image (ie, not map projected)
    Cube cube;
    cube.open(from);

    if (cube.isProjected()) {
        QString msg = "Input images is a map projected cube ... not a level 1 image";
        throw IException(IException::User, msg, _FILEINFO_);
    }

    // Initialize the camera
    Cube *input = p.SetInputCube("FROM");
    Pvl *cubeHeader = input->label();
    Camera *cam = input->camera();
    CameraDetectorMap *detectorMap = cam->DetectorMap();
    CameraFocalPlaneMap *focalMap = cam->FocalPlaneMap();
    CameraDistortionMap *distortionMap = cam->DistortionMap();
    CameraGroundMap *groundMap = cam->GroundMap();

    // Make sure the image contains the InstrumentPointing (aka CK) blob/table
    PvlGroup test = cube.label()->findGroup("Kernels", Pvl::Traverse);
    QString InstrumentPointing = (QString) test["InstrumentPointing"];
    if (InstrumentPointing != "Table") {
        QString msg = "Input image does not contain needed SPICE blobs...run spiceinit with attach=yes.";
        throw IException(IException::User, msg, _FILEINFO_);
    }

    // Open output line scanner keyword file
    ofstream toStrm;
    toStrm.open(to.toAscii().data(), ios::trunc);
    if (toStrm.bad()) {
        QString msg = "Unable to open output TO file";
        throw IException(IException::User, msg, _FILEINFO_);
    }

    // Get required keywords from instrument and band groups
    PvlGroup inst = cube.label()->findGroup("Instrument", Pvl::Traverse);
    QString instrumentId = (QString) inst["InstrumentId"];

    bool     isMocNA = false;
//TO DO: UNCOMMENT THIS LINES ONCE MOC IS WORKING IN SS
//  bool     isMocWARed = false;
    bool     isHiRise = false;
    bool     isCTX = false;
    bool     isLroNACL = false;
    bool     isLroNACR = false;
    bool     isHRSC = false;
//TO DO: UNCOMMENT THESE LINE ONCE MOC IS WORKING IN SS
//  if (instrumentId == "MOC") {
//    PvlGroup band = cube.label()->findGroup("BandBin", Pvl::Traverse);
//    QString filter = (QString) band["FilterName"];
//
//    if (strcmp(filter.toAscii().data(), "BROAD_BAND") == 0)
//      isMocNA = true;
//    else if (strcmp(filter.toAscii().data(), "RED") == 0)
//      isMocWARed = true;
//    else if (strcmp(filter.toAscii().data(), "BLUE") == 0) {
//      QString msg = "MOC WA Blue filter images not supported for Socet Set mapping";
//      throw IException(IException::User, msg, _FILEINFO_);
//    }
//  }
//  else if (instrumentId == "IdealCamera") {
//TO DO: DELETE THIS LINE ONCE MOC IS WORKING IN SS
    if (instrumentId == "IdealCamera") {
        PvlGroup orig = cube.label()->findGroup("OriginalInstrument",  Pvl::Traverse);
        QString origInstrumentId = (QString) orig["InstrumentId"];
        if (origInstrumentId == "HIRISE") {
            isHiRise = true;
        }
        else {
            QString msg = "Unsupported instrument: " + origInstrumentId;
            throw IException(IException::User, msg, _FILEINFO_);
        }
    }
    else if (instrumentId == "HIRISE") {
        isHiRise = true;
    }
    else if (instrumentId == "CTX") {
        isCTX = true;
    }
    else if (instrumentId == "NACL") {
        isLroNACL = true;
    }
    else if (instrumentId == "NACR") {
        isLroNACR = true;
    }
//TO DO: UNCOMMENT THIS LINE ONCE HRSC IS WORKING IN SS
//  else if (instrumentId == "HRSC") isHRSC = true;
    else {
        QString msg = "Unsupported instrument: " + instrumentId;
        throw IException(IException::User, msg, _FILEINFO_);
    }

    int ikCode = cam->naifIkCode();

    // Get Focal Length.
    // NOTE:
    //   For MOC Wide Angle, cam->focal_length returns the focal length
    //      in pixels, so we must convert from pixels to mm using the PIXEL_SIZE
    //      of 0.007 mm gotten from $ISIS3DATA/mgs/kernels/ik/moc20.ti.  (The
    //      PIXEL_PITCH value gotten from cam->PixelPitch is 1.0 since the
    //      focal length used by ISIS in this case is in pixels)
    //      For reference: the MOC WA blue filter pixel size needs an adjustment
    //      of 1.000452 (see p_scale in MocWideAngleDistortionMap.cpp), so that
    //      the final blue filter pixel size = (0.007 / 1.000452)
    //
    //   For all other cameras, cam->focal_length returns the focal
    //      length in mm, as needed by Socet Set

    double focal = cam->FocalLength();  // focal length returned in mm

//TO DO: UNCOMMENT THESE LINES ONCE HRSC and MOC IS WORKING IN SS
//  if (isMocWARed)
//    focal = focal * 0.007;  // pixel to mm conversion
//  else if (isHRSC)
//  {
//    switch (ikCode) {
//      case -41219:                   //S1: fwd stereo
//        focal = 184.88;
//        break;
//      case -41218:                   //IR: infra-red
//        focal = 181.57;
//        break;
//      case -41217:                   //P1: fwd photo
//        focal = 179.16;
//        break;
//      case -41216:                   // GREEN
//        focal = 175.31;
//        break;
//      case -41215:                   // NADIR
//        focal = 175.01;
//        break;
//      case -41214:                   // BLUE
//        focal = 175.53;
//        break;
//      case -41213:                   // P2: aft photo
//        focal = 179.19;
//        break;
//      case -41212:                   // RED
//        focal = 181.77;
//        break;
//      case -41211:                   // S2: aft stereo
//        focal = 184.88;
//        break;
//      default:
//        break;
//    }
//  }

    // Get instrument summing modes
    int csum = (int) detectorMap->SampleScaleFactor();
    int dsum = (int) detectorMap->LineScaleFactor();

    if (isLroNACL || isLroNACR || isHRSC)
        dsum = csum;

    // Calculate location of boresight in image space, these are zero-based values
    //
    // Note: For MOC NA, the boresight is at the image center
    //       For MOC WA, MRO HiRISE, MRO CTX, LRO_NACL, LRO_NACR and HRSC the
    //       boresight is not at the detector center, but the boresight is at the
    //       center of a NOPROJ'ED MRO HIRISE image

    // Get line/samp of boresight pixel in detector space (summing == 1)
    focalMap->SetFocalPlane(0.0, 0.0);
    double detectorBoresightSample = focalMap->DetectorSample();
    double detectorBoresightLine = focalMap->DetectorLine();

    // Convert sample of boresight pixel in detector into image space
    // (summing, etc., is accounted for.)
    detectorMap->SetDetector(detectorBoresightSample, detectorBoresightLine);
    double boresightSample = detectorMap->ParentSample();

    // Set Atmospheric correction coefficients to 0
    double atmco[4] = {0.0, 0.0, 0.0, 0.0};

    // Get totalLines, totalSamples and account for summed images
    int totalLines = cube.lineCount();
    int totalSamples = cube.sampleCount();

    // Get the Interval Time in seconds and calculate
    // scan duration in seconds
    double scanDuration = 0.0;
    double intTime = 0.0;

//TO DO: UNCOMMENT THESE LINES ONCE HRSC IS WORKING IN SS
//  int numIntTimes = 0.0;
//  vector<LineRateChange> lineRates;
//  if (isHRSC) {
//    numIntTimes = GetHRSCLineRates(&cube, lineRates, totalLines, HRSCNadirCenterTime);
//    if (numIntTimes == 1) {
//      LineRateChange lrc = lineRates.at(0);
//      intTime = lrc.GetLineScanRate();
//    }
//    if (numIntTimes <= 0) {
//      QString msg = "HRSC: Invalid number of scan times";
//      throw IException(IException::Programmer, msg, _FILEINFO_);
//    }
//    else
//      scanDuration = GetHRSCScanDuration(lineRates, totalLines);
//  }
//  else {
//
//  TO DO: indent the following two lines when HRSC is working in SS
    intTime = detectorMap->LineRate();  //LineRate is in seconds
    scanDuration = intTime * totalLines;
//TO DO: UNCOMMENT THIS LINE ONCE HRSC IS WORKING IN SS
//  }

    // For reference, this is the code if calculating interval time
    // via LineExposureDuration keyword off image labels:
    //
    // if (isMocNA || isMocWARed)
    //   intTime = exposureDuration * (double) dsum / 1000.0;
    // else if (isHiRise)
    //   intTime = exposureDuration * (double) dsum / 1000000.0;

    // Get along and cross scan pixel size for NA and WA sensors.
    // NOTE:
    //     1) The MOC WA pixel size is gotten from moc20.ti and is 7 microns
    //         HRSC pixel size is from the Instrument Addendum file
    //     2) For others, cam->PixelPitch() returns the pixel pitch (size) in mm.
    double alongScanPxSize = 0.0;
    double crossScanPxSize = 0.0;
//TO DO: UNCOMMENT THESE LINES ONCE MOC IS WORKING IN SS
//  if (isMocWARed || isHRSC) {
//    alongScanPxSize = csum * 0.007;
//    crossScanPxSize = dsum * 0.007;
//  }
//  else {
//
//  TO DO: indent the following 24 lines when HRSC is working in SS
    crossScanPxSize = dsum * cam->PixelPitch();

    // Get the ephemeris time, ground position and undistorted focal plane X
    // coordinate at the center line/samp of image
    cam->SetImage(cube.sampleCount() / 2.0, cube.lineCount() / 2.0);

    double tMid = cam->time().Et();

    const double latCenter = cam->UniversalLatitude();
    const double lonCenter = cam->UniversalLongitude();
    const double radiusCenter = cam->LocalRadius().meters();

    double uXCenter = distortionMap->UndistortedFocalPlaneX();

    // from the ground position at the image center, increment the ephemeris
    // time by the line rate and map the ground position into the sensor in
    // undistorted focal plane coordinates

    cam->setTime(iTime(tMid + intTime));
    double uX, uY;
    groundMap->GetXY(latCenter, lonCenter, radiusCenter, &uX, &uY);

    // the along scan pixel size is the difference in focal plane X coordinates
    alongScanPxSize = abs(uXCenter - uX);

//TO DO: UNCOMMENT THIS LINE ONCE MOC and HRSC IS WORKING IN SS
//  }

    // Now that we have totalLines, totalSamples, alongScanPxSize and
    // crossScanPxSize, fill the Interior Orientation Coefficient arrays
    double ioCoefLine[10];
    double ioCoefSample[10];
    for (int i = 0; i <= 9; i++) {
        ioCoefLine[i] = 0.0;
        ioCoefSample[i] = 0.0;
    }

    ioCoefLine[0] = totalLines / 2.0;
    ioCoefLine[1] = 1.0 / alongScanPxSize;

    ioCoefSample[0] = totalSamples / 2.0;
    ioCoefSample[2] = 1.0 / crossScanPxSize;

    // Update the Rectification Terms found in the base sensor class
    double rectificationTerms[6];
    rectificationTerms[0] = totalLines / 2.0;
    rectificationTerms[1] = 0.0;
    rectificationTerms[2] = 1.0;
    rectificationTerms[3] = totalSamples / 2.0;
    rectificationTerms[4] = 1.0;
    rectificationTerms[5] = 0.0;

    // Fill the triangulation parameters array
    double triParams[18];
    for (int i = 0; i <= 17; i++)
        triParams[i] = 0.0;

    triParams[15] = focal;

    // Set the Center Ground Point at the SOCET Set image, in radians
    double centerGp[3];
    double radii[3] = {0.0, 0.0, 0.0};
    Distance Dradii[3];

    cam->radii(Dradii);
    radii[0] = Dradii[0].kilometers();
    radii[1] = Dradii[1].kilometers();
    radii[2] = Dradii[2].kilometers();

    cam->SetImage(boresightSample, totalLines / 2.0);

    centerGp[0] = DEG2RAD *
                  TProjection::ToPlanetographic(cam->UniversalLatitude(), radii[0], radii[2]);
    centerGp[1] = DEG2RAD * TProjection::To180Domain(cam->UniversalLongitude());
    centerGp[2] = 0.0;
    //**** NOTE: in the import_pushbroom SOCET SET program, centerGp[2] will be set to the SS
    //**** project's gp_origin_z

    // Now get keyword values that depend on ephemeris data.

    // First get the ephemeris time and camera Lat Lon at image center line, boresight sample.
    double centerLine = double(totalLines) / 2.0;

    cam->SetImage(boresightSample, centerLine); //set to boresight of image
    double etCenter = cam->time().Et();

    // Get the sensor position at the image center in ographic lat,
    // +E lon domain 180 coordinates, radians, height in meters
    double sensorPosition[3] = {0.0, 0.0, 0.0};
    double ocentricLat, e360Lon;
    cam->subSpacecraftPoint(ocentricLat, e360Lon);
    sensorPosition[0] = DEG2RAD * TProjection::ToPlanetographic(ocentricLat, radii[0], radii[2]);
    sensorPosition[1] = DEG2RAD * TProjection::To180Domain(e360Lon);
    sensorPosition[2] = cam->SpacecraftAltitude() * 1000.0;

    // Build the ephem data.  If the image label contains the InstrumentPosition
    // table, use it as a guide for number and spacing of Ephem points.
    // Otherwise (i.e, for dejittered HiRISE images), the number and spacing of
    // ephem points based on hardcoded dtEphem value

    // Using the InstrumentPosition table as a guide build the ephem data
    QList< QList<double> > ephemPts;
    QList< QList<double> > ephemRates;

    PvlGroup kernels = cube.label()->findGroup("Kernels", Pvl::Traverse);
    QString InstrumentPosition = (QString) kernels["InstrumentPosition"];

    int numEphem = 0;      // number of ephemeris points
    double dtEphem = 0.0;  // delta time of ephemeris points, seconds
    if (InstrumentPosition == "Table") {
        // Labels contain SPK blob
        // set up Ephem pts/rates number and spacing
        Table tablePosition("InstrumentPosition", cubeHeader->fileName());
        numEphem = tablePosition.Records();

        // increase the number of ephem nodes by 20%.  This is somewhat random but
        // generally intended to compensate for having equally time spaced nodes
        // instead of of the potentially more efficient placement used by spiceinit
        numEphem = int(double(numEphem) * 1.2);

        // if numEphem calcutated from SPICE blobs is too sparse for SOCET Set,
        // mulitiply it by a factor of 30
        // (30X was settled upon emperically.  In the future, make this an input parameter)
        if (numEphem <= 10) numEphem = tablePosition.Records() * 30;

        // make the number of nodes odd
        numEphem  = (numEphem % 2) == 1 ? numEphem : numEphem + 1;

        // SOCET has a max number of ephem pts of 10000, and we're going to add twenty...
        if (numEphem > 10000 - 20) numEphem = 9979;

        dtEphem = scanDuration / double(numEphem);

        //build the tables of values
        double et = etCenter - (((numEphem - 1) / 2) * dtEphem);
        for (int i = 0; i < numEphem; i++) {
            cam->setTime(iTime(et));
            SpiceRotation *bodyRot = cam->bodyRotation();
            vector<double> pos = bodyRot->ReferenceVector(cam->instrumentPosition()->Coordinate());
//TO DO: UNCOMMENT THE FOLLOWING LINE WHEN VELOCITY BLOBS ARE CORRECT IN ISIS
            //vector<double> vel = bodyRot->ReferenceVector(cam->instrumentPosition()->Velocity());

            //Add the ephemeris position and velocity to their respective lists, in meters and meters/sec
            QList<double> ephemPt;
            QList<double> ephemRate;
            ephemPts.append(ephemPt << pos[0] * 1000 << pos[1] * 1000 << pos[2] * 1000);
//TO DO: UNCOMMENT THE FOLLOWING LINE WHEN VELOCITY BLOBS ARE CORRECT IN ISIS
            //ephemRates.append(ephemRate << vel[0] * 1000 << vel[1] * 1000 << vel[2] * 1000);

            et += dtEphem;
        }

//TO DO: WHEN VELOCITY BLOBS ARE CORRECT IN ISIS, linearlly interpolate 10 nodes rather than 11
//       (need 11 now for computation of velocity at first and last ephemeris point)
        // linearlly interpolate 11 additional nodes before line 1 (SOCET requires this)
        for (int i = 0; i < 11; i++) {
            double vec[3] = {0.0, 0.0, 0.0};
            vec[0] = ephemPts[0][0] + (ephemPts[0][0] - ephemPts[1][0]);
            vec[1] = ephemPts[0][1] + (ephemPts[0][1] - ephemPts[1][1]);
            vec[2] = ephemPts[0][2] + (ephemPts[0][2] - ephemPts[1][2]);
            QList<double> ephemPt;
            ephemPts.prepend (ephemPt << vec[0] << vec[1] << vec[2]);

//TO DO: UNCOMMENT THE FOLLOWING LINES WHEN VELOCITY BLOBS ARE CORRECT IN ISIS
            //vec[0] = ephemRates[0][0] + (ephemRates[0][0] - ephemRates[1][0]);
            //vec[1] = ephemRates[0][1] + (ephemRates[0][1] - ephemRates[1][1]);
            //vec[2] = ephemRates[0][2] + (ephemRates[0][2] - ephemRates[1][2]);
            //QList<double> ephemRate;
            //ephemRates.prepend (ephemRate << vec[0] << vec[1] << vec[2]);
        }

//TO DO: WHEN VELOCITY BLOBS ARE CORRECT IN ISIS, linearlly interpolate 10 nodes rather than 11
//       (need 11 now for computation of velocity at first and last ephemeris point)
        // linearlly interpolate 11 additional nodes after the last line (SOCET requires this)
        for (int i = 0; i < 11; i++) {
            double vec[3] = {0.0, 0.0, 0.0};
            int index = ephemPts.size() - 1;
            vec[0] = ephemPts[index][0] + (ephemPts[index][0] - ephemPts[index - 1][0]);
            vec[1] = ephemPts[index][1] + (ephemPts[index][1] - ephemPts[index - 1][1]);
            vec[2] = ephemPts[index][2] + (ephemPts[index][2] - ephemPts[index - 1][2]);
            QList<double> ephemPt;
            ephemPts.append(ephemPt << vec[0] << vec[1] << vec[2]);

//TO DO: UNCOMMENT THE FOLLOWING LINES WHEN VELOCITY BLOBS ARE CORRECT IN ISIS
            //vec[0] = ephemRates[index][0] + (ephemRates[index][0] - ephemRates[index - 1][0]);
            //vec[1] = ephemRates[index][1] + (ephemRates[index][1] - ephemRates[index - 1][1]);
            //vec[2] = ephemRates[index][2] + (ephemRates[index][2] - ephemRates[index - 1][2]);
            //QList<double> ephemRate;
            //ephemRates.append(ephemRate << vec[0] << vec[1] << vec[2]);
        }

        numEphem += 20;

//TO DO: DELETE THE FOLLOWING LINES WHEN VELOCITY BLOBS ARE CORRECT IN ISIS
        // Compute the spacecraft velocity at each ephemeris point
        double deltaTime = 2.0 * dtEphem;
        for (int i = 0; i < numEphem; i++) {
            double vec[3] = {0.0, 0.0, 0.0};
            vec[0] = (ephemPts[i+2][0] - ephemPts[i][0]) / deltaTime;
            vec[1] = (ephemPts[i+2][1] - ephemPts[i][1]) / deltaTime;
            vec[2] = (ephemPts[i+2][2] - ephemPts[i][2]) / deltaTime;
            QList<double> ephemRate;
            ephemRates.append(ephemRate << vec[0] << vec[1] << vec[2]);
        }

    }
    else {
        // Calculate the number of ephemeris points that are needed, based on the
        // value of dtEphem (Delta-Time-Ephemeris).  SOCET SET needs the ephemeris
        // points to exceed the image range for interpolation.  For now, attempt a
        // padding of 10 ephemeris points on either side of the image.

        if (isMocNA || isHiRise || isCTX || isLroNACL || isLroNACR || isHRSC)
            // Try increment of every 300 image lines
            dtEphem = 300 * intTime;  // Make this a user definable increment?
        else // Set increment for WA images to one second
            dtEphem = 1.0;

        // Pad by 10 ephem pts on each side of the image
        numEphem = (int)(scanDuration / dtEphem) + 20;

        // if numEphem is even, make it odd so that the number of ephemeris points
        // is equal on either side of T_CENTER
        if ((numEphem % 2) == 0)
            numEphem++;

//TO DO: DELETE THE FOLLOWING LINE WHEN VELOCITY BLOBS ARE CORRECT IN ISIS
        numEphem = numEphem + 2; // Add two for calcuation of velocity vectors...

        // Find the ephemeris time for the first ephemeris point, and from that, get
        // to_ephem needed by SOCET (to_ephem is relative to etCenter)
        double et = etCenter - (((numEphem - 1) / 2) * dtEphem);
        for (int i = 0; i < numEphem; i++) {
            cam->setTime(iTime(et));
            SpiceRotation *bodyRot = cam->bodyRotation();
            vector<double> pos = bodyRot->ReferenceVector(cam->instrumentPosition()->Coordinate());
//TO DO: UNCOMMENT THE FOLLOWING LINE WHEN VELOCITY BLOBS ARE CORRECT IN ISIS
            //vector<double> vel = bodyRot->ReferenceVector(cam->instrumentPosition()->Velocity());

            //Add the ephemeris position and velocity to their respective lists, in meters and meters/sec
            QList<double> ephemPt;
            QList<double> ephemRate;
            ephemPts.append(ephemPt << pos[0] * 1000 << pos[1] * 1000 << pos[2] * 1000);
//TO DO: UNCOMMENT THE FOLLOWING LINE WHEN VELOCITY BLOBS ARE CORRECT IN ISIS
            //ephemRates.append(ephemRate << vel[0] * 1000 << vel[1] * 1000 << vel[2] * 1000);

            et += dtEphem;
        }
//TO DO: DELETE THE FOLLOWING LINES WHEN VELOCITY BLOBS ARE CORRECT IN ISIS
        // Compute the spacecraft velocity at each ephemeris point
        // (We must do this when blobs are not attached because the Spice Class
        // stores in memory the same data that would be in a blob...even when reading NAIF kernels)
        double deltaTime = 2.0 * dtEphem;
        numEphem = numEphem - 2; // set numEphem back to the number we need output
        for (int i = 0; i < numEphem; i++) {
            double vec[3] = {0.0, 0.0, 0.0};
            vec[0] = (ephemPts[i+2][0] - ephemPts[i][0]) / deltaTime;
            vec[1] = (ephemPts[i+2][1] - ephemPts[i][1]) / deltaTime;
            vec[2] = (ephemPts[i+2][2] - ephemPts[i][2]) / deltaTime;
            QList<double> ephemRate;
            ephemRates.append(ephemRate << vec[0] << vec[1] << vec[2]);
        }
    }

    //update ephem stats
    double etFirstEphem = etCenter - (((numEphem - 1) / 2) * dtEphem);
    double t0Ephem = etFirstEphem - etCenter;

    // Using the intrumentPointing table as a guide build the quarternions
    // for simplicity sake we'll leave the mountingAngles as identity
    // and store the complete rotation from body fixed to camera in the
    // quarternions

    //set up quaternions number and spacing
    Table tablePointing("InstrumentPointing", cubeHeader->fileName());

    //number of quaternions
    int numQuaternions = tablePointing.Records();

    // increase the number of quaternions nodes by 20%. This is somewhat random but
    // generally intended to compensate for having equally time spaced nodes
    // instead of of the potentially more efficient placement used by spiceinit
    numQuaternions = (int)(numQuaternions * 1.2);

    // if numQuaternions calcutated from SPICE blobs is too sparse for SOCET Set,
    // mulitiply it by a factor of 30
    // (30X was settled upon emperically.  In the future, make this an input parameter)
    if (numQuaternions <= 10) numQuaternions = tablePointing.Records() * 30;

    //make the number of nodes odd
    numQuaternions = (numQuaternions % 2) == 1 ? numQuaternions : numQuaternions + 1;

    // SOCET has a max number of quaternions of 20000, and we're going to add twenty...
    if (numQuaternions > 20000 - 20) numQuaternions = 19179;

    double dtQuat = scanDuration / double(numQuaternions);

    // build the tables of values
    QList< QList<double> > quaternions;
    double et = etCenter - (((numQuaternions - 1) / 2) * dtQuat);

    for (int i = 0; i < numQuaternions; i++) {
        cam->setTime(iTime(et));
        vector<double> j2000ToBodyFixedMatrixVector = cam->bodyRotation()->Matrix();
        vector<double> j2000ToCameraMatrixVector = cam->instrumentRotation()->Matrix();
        double quaternion[4] = {0.0, 0.0, 0.0, 0.0};

        double j2000ToBodyFixedRotationMatrix[3][3], //rotation from J2000 to target (aka body, planet)
               j2000ToCameraRotationMatrix[3][3], //rotation from J2000 to spacecraft
               cameraToBodyFixedRotationMatrix[3][3]; //rotation from camera to target

        // reformat vectors to 3x3 rotation matricies
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 3; k++) {
                j2000ToBodyFixedRotationMatrix[j][k] = j2000ToBodyFixedMatrixVector[3 * j + k];
                j2000ToCameraRotationMatrix[j][k] = j2000ToCameraMatrixVector[3 * j + k];
            }
        }

        // get the quaternion
        mxmt_c(j2000ToBodyFixedRotationMatrix, j2000ToCameraRotationMatrix,
               cameraToBodyFixedRotationMatrix);
        m2q_c(cameraToBodyFixedRotationMatrix, quaternion);

        // add the quaternion to the list of quaternions
        QList<double> quat;
        quaternions.append(quat << quaternion[1] << quaternion[2] << quaternion[3] <<
                           quaternion[0]);
        //note also that the order is changed to match socet

        et += dtQuat;
    }

    // linearlly interpolate 10 additional nodes before the first quaternion (SOCET requires this)
    for (int i = 0; i < 10; i++) {
        double vec[4] = {0.0, 0.0, 0.0, 0.0};
        vec[0] = quaternions[0][0] + (quaternions[0][0] - quaternions[1][0]);
        vec[1] = quaternions[0][1] + (quaternions[0][1] - quaternions[1][1]);
        vec[2] = quaternions[0][2] + (quaternions[0][2] - quaternions[1][2]);
        vec[3] = quaternions[0][3] + (quaternions[0][3] - quaternions[1][3]);
        QList<double> quat;
        quaternions.prepend (quat << vec[0] << vec[1] << vec[2] << vec[3]);
    }

    // linearlly interpolate 10 additional nodes after the last quaternion (SOCET requires this)
    for (int i = 0; i < 10; i++) {
        double vec[4] = {0.0, 0.0, 0.0, 0.0};
        int index = quaternions.size() - 1;
        vec[0] = quaternions[index][0] + (quaternions[index][0] - quaternions[index - 1][0]);
        vec[1] = quaternions[index][1] + (quaternions[index][1] - quaternions[index - 1][1]);
        vec[2] = quaternions[index][2] + (quaternions[index][2] - quaternions[index - 1][2]);
        vec[3] = quaternions[index][3] + (quaternions[index][3] - quaternions[index - 1][3]);
        QList<double> quat;
        quaternions.append(quat << vec[0] << vec[1] << vec[2] << vec[3]);
    }

    //update quaternions stats
    numQuaternions += 20;

    //ephemeris time of the first quarternion
    double et0Quat = etCenter - (((numQuaternions - 1) / 2) * dtQuat);

    //quadrtic time of the first quarternion
    double qt0Quat = et0Quat - etCenter;

    //query remaing transformation parameters from Camera Classes
    //transformation to distortionless focal plane
    double zDirection = distortionMap->ZDirection();

    //transformation from DistortionlessFocalPlane to FocalPlane
    vector<double> opticalDistCoefs = distortionMap->OpticalDistortionCoefficients();

    // For instruments with less than 3 distortion coefficients, set the
    // unused ones to 0.0
    opticalDistCoefs.resize(3, 0);

    //transformation from focal plane to detector
    const double *iTransS = focalMap->TransS();
    const double *iTransL = focalMap->TransL();
    double detectorSampleOrigin = focalMap->DetectorSampleOrigin();
    double detectorLineOrigin = focalMap->DetectorLineOrigin();

    //transformation from dectector to cube
    double startingSample = detectorMap->AdjustedStartingSample();
    double startingLine = detectorMap->AdjustedStartingLine();
    double sampleSumming = detectorMap->SampleScaleFactor();
    double etStart = ((LineScanCameraDetectorMap *)detectorMap)->StartTime();
    double lineOffset = focalMap->DetectorLineOffset();

    // We are done with computing keyword values, so output the Line Scanner
    // Keyword file.

    // This is the SOCET SET base sensor class keywords portion of support file:
    toStrm.setf(ios::scientific);
    toStrm << "RECTIFICATION_TERMS" << endl;
    toStrm << "        " << setprecision(14) << rectificationTerms[0] << " " <<
           rectificationTerms[1] << " " << rectificationTerms[2] << endl;
    toStrm << "        " << rectificationTerms[3] << " " << rectificationTerms[4] <<
           " " << rectificationTerms[5] << endl;

    toStrm << "GROUND_ZERO ";
    toStrm << centerGp[0] << " " << centerGp[1] << " " << centerGp[2] << endl;

    toStrm << "LOAD_PT ";
    toStrm << centerGp[0] << " " << centerGp[1] << " " << centerGp[2] << endl;

    toStrm << "COORD_SYSTEM 1" << endl;

    toStrm << "IMAGE_MOTION 0" << endl;

    // This is the line scanner sensor model portion of support file:
    toStrm << "SENSOR_TYPE USGSAstroLineScanner" << endl;
    toStrm << "SENSOR_MODE UNKNOWN" << endl;

    toStrm << "FOCAL " << focal << endl;

    toStrm << "ATMCO";
    for (int i = 0; i < 4; i++) toStrm << " " << atmco[i];
    toStrm << endl;

    toStrm << "IOCOEF_LINE";
    for (int i = 0; i < 10; i++) toStrm << " " << ioCoefLine[i];
    toStrm << endl;

    toStrm << "IOCOEF_SAMPLE";
    for (int i = 0; i < 10; i++) toStrm << " " << ioCoefSample[i];
    toStrm << endl;

    toStrm << "ABERR    0" << endl;
    toStrm << "ATMREF   0" << endl;
    toStrm << "PLATFORM   1" << endl;
    toStrm << "SOURCE_FLAG  1" << endl;
    toStrm << "SINGLE_EPHEMERIDE  0" << endl;

    //Note, for TRI_PARAMETERS, we print the first element separate from the rest so that the array
    //starts in the first column.  Otherwise, SOCET Set will treat the array as a comment
    toStrm << "TRI_PARAMETERS" << endl;
    toStrm << triParams[0];
    for (int i = 1; i < 18; i++) toStrm << " " << triParams[i];
    toStrm << endl;

    toStrm << setprecision(25) << "T_CENTER  ";
    double tCenter = 0.0;
//TO DO: UNCOMMENT THESE LINES ONCE HRSC IS WORKING IN SS
//  if (isHRSC) {
//    tCenter = etCenter - HRSCNadirCenterTime;
//    toStrm << tCenter << endl;
//  }
//  else
    toStrm << tCenter << endl;

    toStrm << "DT_EPHEM  " << dtEphem << endl;

    toStrm << "T0_EPHEM  ";
//TO DO: UNCOMMENT THESE LINES ONCE HRSC IS WORKING IN SS
//  if (isHRSC) {
//    double t = tCenter + t0Ephem;
//    toStrm << t << endl;
//  }
//  else
    toStrm << t0Ephem << endl;

    toStrm << "NUMBER_OF_EPHEM   " << numEphem << endl;

    toStrm << "EPHEM_PTS" << endl;
//TO DO: DELETE THE FOLLOWING LINE WHEN VELOCITY BLOBS ARE CORRECT IN ISIS
    for (int i = 1; i <= numEphem; i++) {
//TO DO: UNCOMMENT THE FOLLOWING LINE WHEN VELOCITY BLOBS ARE CORRECT IN ISIS
        //for (int i = 0; i < numEphem; i++) {
        toStrm << " " << ephemPts[i][0];
        toStrm << " " << ephemPts[i][1];
        toStrm << " " << ephemPts[i][2] << endl;
    }

    toStrm  << "\n\nEPHEM_RATES" << endl;
    for (int i = 0; i < numEphem; i++) {
        toStrm << " " << ephemRates[i][0];
        toStrm << " " << ephemRates[i][1];
        toStrm << " " << ephemRates[i][2] << endl;
    }

    toStrm << "\n\nDT_QUAT " << dtQuat << endl;
    toStrm << "T0_QUAT " << qt0Quat << endl;
    toStrm << "NUMBER_OF_QUATERNIONS  " << numQuaternions << endl;
    toStrm << "QUATERNIONS" << endl;
    for (int i = 0; i < numQuaternions; i++) {
        toStrm << " " << quaternions[i][0];
        toStrm << " " << quaternions[i][1];
        toStrm << " " << quaternions[i][2];
        toStrm << " " << quaternions[i][3] << endl;
    }

    toStrm << "\n\nSCAN_DURATION " << scanDuration << endl;

    //  UNCOMMENT toStrm << "\nNUMBER_OF_INT_TIMES " << numIntTimes << endl;
    //
    //  if (isHRSC) {
    //    toStrm  << "INT_TIMES" << endl;
    //    for (int i = 0; i < numIntTimes; i++) {
    //      LineRateChange lr = lineRates.at(i);
    //      toStrm << " " << lr.GetStartEt();
    //      toStrm << " " << lr.GetLineScanRate();
    //      toStrm << " " << lr.GetStartLine() << endl;
    //    }
    //  }
    //  else
    toStrm << "INT_TIME " << intTime << endl;

    toStrm << "\nALONG_SCAN_PIXEL_SIZE  " << alongScanPxSize << endl;
    toStrm << "CROSS_SCAN_PIXEL_SIZE  " << crossScanPxSize << endl;

    toStrm << "\nCENTER_GP";
    for (int i = 0; i < 3; i++) toStrm << " " << centerGp[i];
    toStrm << endl;

    toStrm << "SENSOR_POSITION";
    for (int i = 0; i < 3; i++) toStrm << " " << sensorPosition[i];
    toStrm << endl;

    toStrm << "MOUNTING_ANGLES";
    double mountingAngles[3] = {0.0, 0.0, 0.0};
    for (int i = 0; i < 3; i++) toStrm << " " << mountingAngles[i];
    toStrm << endl;

    toStrm << "\nTOTAL_LINES " << totalLines << endl;
    toStrm << "TOTAL_SAMPLES " << totalSamples << endl;
    toStrm << "\n\n\n" << endl;

    toStrm << "IKCODE  " << ikCode << endl;
    toStrm << "ISIS_Z_DIRECTION  " << zDirection << endl;

    toStrm << "OPTICAL_DIST_COEF";
    for (int i = 0; i < 3; i++) toStrm << " " << opticalDistCoefs[i];
    toStrm << endl;

    toStrm << "ITRANSS";
    for (int i = 0; i < 3; i++) toStrm << " " << iTransS[i];
    toStrm << endl;

    toStrm << "ITRANSL";
    for (int i = 0; i < 3; i++) toStrm << " " << iTransL[i];
    toStrm << endl;

    toStrm << "DETECTOR_SAMPLE_ORIGIN " << detectorSampleOrigin << endl;
    toStrm << "DETECTOR_LINE_ORIGIN " << detectorLineOrigin << endl;
    toStrm << "DETECTOR_LINE_OFFSET  " << lineOffset << endl;
    toStrm << "DETECTOR_SAMPLE_SUMMING  " << sampleSumming << endl;

    toStrm << "STARTING_SAMPLE " << startingSample << endl;
    toStrm << "STARTING_LINE " << startingLine << endl;
    toStrm << "STARTING_EPHEMERIS_TIME " << setprecision(25) << etStart << endl;
    toStrm << "CENTER_EPHEMERIS_TIME " << etCenter << endl;

} // end main
예제 #22
0
bool
Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
{
    // If the section was NULL, only load address is going to work unless we are
    // trying to deref a pointer
    SectionSP section_sp (GetSection());
    if (!section_sp && style != DumpStyleResolvedPointerDescription)
        style = DumpStyleLoadAddress;

    ExecutionContext exe_ctx (exe_scope);
    Target *target = exe_ctx.GetTargetPtr();
    // If addr_byte_size is UINT32_MAX, then determine the correct address
    // byte size for the process or default to the size of addr_t
    if (addr_size == UINT32_MAX)
    {
        if (target)
            addr_size = target->GetArchitecture().GetAddressByteSize ();
        else
            addr_size = sizeof(addr_t);
    }

    Address so_addr;
    switch (style)
    {
    case DumpStyleInvalid:
        return false;

    case DumpStyleSectionNameOffset:
        if (section_sp)
        {
            section_sp->DumpName(s);
            s->Printf (" + %" PRIu64, m_offset.load());
        }
        else
        {
            s->Address(m_offset, addr_size);
        }
        break;

    case DumpStyleSectionPointerOffset:
        s->Printf("(Section *)%p + ", static_cast<void*>(section_sp.get()));
        s->Address(m_offset, addr_size);
        break;

    case DumpStyleModuleWithFileAddress:
        if (section_sp)
        {
            s->Printf("%s[", section_sp->GetModule()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
        }
        // Fall through
    case DumpStyleFileAddress:
        {
            addr_t file_addr = GetFileAddress();
            if (file_addr == LLDB_INVALID_ADDRESS)
            {
                if (fallback_style != DumpStyleInvalid)
                    return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
                return false;
            }
            s->Address (file_addr, addr_size);
            if (style == DumpStyleModuleWithFileAddress && section_sp)
                s->PutChar(']');
        }
        break;

    case DumpStyleLoadAddress:
        {
            addr_t load_addr = GetLoadAddress (target);
            if (load_addr == LLDB_INVALID_ADDRESS)
            {
                if (fallback_style != DumpStyleInvalid)
                    return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
                return false;
            }
            s->Address (load_addr, addr_size);
        }
        break;

    case DumpStyleResolvedDescription:
    case DumpStyleResolvedDescriptionNoModule:
    case DumpStyleResolvedDescriptionNoFunctionArguments:
    case DumpStyleNoFunctionName:
        if (IsSectionOffset())
        {
            uint32_t pointer_size = 4;
            ModuleSP module_sp (GetModule());
            if (target)
                pointer_size = target->GetArchitecture().GetAddressByteSize();
            else if (module_sp)
                pointer_size = module_sp->GetArchitecture().GetAddressByteSize();

            bool showed_info = false;
            if (section_sp)
            {
                SectionType sect_type = section_sp->GetType();
                switch (sect_type)
                {
                case eSectionTypeData:
                    if (module_sp)
                    {
                        SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
                        if (sym_vendor)
                        {
                            Symtab *symtab = sym_vendor->GetSymtab();
                            if (symtab)
                            {
                                const addr_t file_Addr = GetFileAddress();
                                Symbol *symbol = symtab->FindSymbolContainingFileAddress (file_Addr);
                                if (symbol)
                                {
                                    const char *symbol_name = symbol->GetName().AsCString();
                                    if (symbol_name)
                                    {
                                        s->PutCString(symbol_name);
                                        addr_t delta = file_Addr - symbol->GetAddressRef().GetFileAddress();
                                        if (delta)
                                            s->Printf(" + %" PRIu64, delta);
                                        showed_info = true;
                                    }
                                }
                            }
                        }
                    }
                    break;

                case eSectionTypeDataCString:
                    // Read the C string from memory and display it
                    showed_info = true;
                    ReadCStringFromMemory (exe_scope, *this, s);
                    break;

                case eSectionTypeDataCStringPointers:
                    {
                        if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
                        {
#if VERBOSE_OUTPUT
                            s->PutCString("(char *)");
                            so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
                            s->PutCString(": ");
#endif
                            showed_info = true;
                            ReadCStringFromMemory (exe_scope, so_addr, s);
                        }
                    }
                    break;

                case eSectionTypeDataObjCMessageRefs:
                    {
                        if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
                        {
                            if (target && so_addr.IsSectionOffset())
                            {
                                SymbolContext func_sc;
                                target->GetImages().ResolveSymbolContextForAddress (so_addr,
                                                                                             eSymbolContextEverything,
                                                                                             func_sc);
                                if (func_sc.function || func_sc.symbol)
                                {
                                    showed_info = true;
#if VERBOSE_OUTPUT
                                    s->PutCString ("(objc_msgref *) -> { (func*)");
                                    so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
#else
                                    s->PutCString ("{ ");
#endif
                                    Address cstr_addr(*this);
                                    cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
                                    func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false, true, true);
                                    if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr))
                                    {
#if VERBOSE_OUTPUT
                                        s->PutCString("), (char *)");
                                        so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
                                        s->PutCString(" (");
#else
                                        s->PutCString(", ");
#endif
                                        ReadCStringFromMemory (exe_scope, so_addr, s);
                                    }
#if VERBOSE_OUTPUT
                                    s->PutCString(") }");
#else
                                    s->PutCString(" }");
#endif
                                }
                            }
                        }
                    }
                    break;

                case eSectionTypeDataObjCCFStrings:
                    {
                        Address cfstring_data_addr(*this);
                        cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size));
                        if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr))
                        {
#if VERBOSE_OUTPUT
                            s->PutCString("(CFString *) ");
                            cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
                            s->PutCString(" -> @");
#else
                            s->PutChar('@');
#endif
                            if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
                                showed_info = true;
                        }
                    }
                    break;

                case eSectionTypeData4:
                    // Read the 4 byte data and display it
                    showed_info = true;
                    s->PutCString("(uint32_t) ");
                    DumpUInt (exe_scope, *this, 4, s);
                    break;

                case eSectionTypeData8:
                    // Read the 8 byte data and display it
                    showed_info = true;
                    s->PutCString("(uint64_t) ");
                    DumpUInt (exe_scope, *this, 8, s);
                    break;

                case eSectionTypeData16:
                    // Read the 16 byte data and display it
                    showed_info = true;
                    s->PutCString("(uint128_t) ");
                    DumpUInt (exe_scope, *this, 16, s);
                    break;

                case eSectionTypeDataPointers:
                    // Read the pointer data and display it
                    {
                        if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
                        {
                            s->PutCString ("(void *)");
                            so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);

                            showed_info = true;
                            if (so_addr.IsSectionOffset())
                            {
                                SymbolContext pointer_sc;
                                if (target)
                                {
                                    target->GetImages().ResolveSymbolContextForAddress (so_addr,
                                                                                                 eSymbolContextEverything,
                                                                                                 pointer_sc);
                                    if (pointer_sc.function || pointer_sc.symbol)
                                    {
                                        s->PutCString(": ");
                                        pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false, true, true);
                                    }
                                }
                            }
                        }
                    }
                    break;

                default:
                    break;
                }
            }

            if (!showed_info)
            {
                if (module_sp)
                {
                    SymbolContext sc;
                    module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything | eSymbolContextVariable, sc);
                    if (sc.function || sc.symbol)
                    {
                        bool show_stop_context = true;
                        const bool show_module = (style == DumpStyleResolvedDescription);
                        const bool show_fullpaths = false; 
                        const bool show_inlined_frames = true;
                        const bool show_function_arguments = (style != DumpStyleResolvedDescriptionNoFunctionArguments);
                        const bool show_function_name = (style != DumpStyleNoFunctionName);
                        if (sc.function == NULL && sc.symbol != NULL)
                        {
                            // If we have just a symbol make sure it is in the right section
                            if (sc.symbol->ValueIsAddress())
                            {
                                if (sc.symbol->GetAddressRef().GetSection() != GetSection())
                                {
                                    // don't show the module if the symbol is a trampoline symbol
                                    show_stop_context = false;
                                }
                            }
                        }
                        if (show_stop_context)
                        {
                            // We have a function or a symbol from the same
                            // sections as this address.
                            sc.DumpStopContext (s, 
                                                exe_scope, 
                                                *this, 
                                                show_fullpaths, 
                                                show_module, 
                                                show_inlined_frames,
                                                show_function_arguments,
                                                show_function_name);
                        }
                        else
                        {
                            // We found a symbol but it was in a different
                            // section so it isn't the symbol we should be
                            // showing, just show the section name + offset
                            Dump (s, exe_scope, DumpStyleSectionNameOffset);
                        }
                    }
                }
            }
        }
        else
        {
            if (fallback_style != DumpStyleInvalid)
                return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
            return false;
        }
        break;

    case DumpStyleDetailedSymbolContext:
        if (IsSectionOffset())
        {
            ModuleSP module_sp (GetModule());
            if (module_sp)
            {
                SymbolContext sc;
                module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything | eSymbolContextVariable, sc);
                if (sc.symbol)
                {
                    // If we have just a symbol make sure it is in the same section
                    // as our address. If it isn't, then we might have just found
                    // the last symbol that came before the address that we are 
                    // looking up that has nothing to do with our address lookup.
                    if (sc.symbol->ValueIsAddress() && sc.symbol->GetAddressRef().GetSection() != GetSection())
                        sc.symbol = NULL;
                }
                sc.GetDescription(s, eDescriptionLevelBrief, target);
                
                if (sc.block)
                {
                    bool can_create = true;
                    bool get_parent_variables = true;
                    bool stop_if_block_is_inlined_function = false;
                    VariableList variable_list;
                    sc.block->AppendVariables (can_create,
                                               get_parent_variables, 
                                               stop_if_block_is_inlined_function, 
                                               &variable_list);
                    
                    const size_t num_variables = variable_list.GetSize();
                    for (size_t var_idx = 0; var_idx < num_variables; ++var_idx)
                    {
                        Variable *var = variable_list.GetVariableAtIndex (var_idx).get();
                        if (var && var->LocationIsValidForAddress (*this))
                        {
                            s->Indent();
                            s->Printf ("   Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
                                       var->GetID(),
                                       var->GetName().GetCString());
                            Type *type = var->GetType();
                            if (type)
                                s->Printf(", type = \"%s\"", type->GetName().GetCString());
                            else
                                s->PutCString(", type = <unknown>");
                            s->PutCString(", location = ");
                            var->DumpLocationForAddress(s, *this);
                            s->PutCString(", decl = ");
                            var->GetDeclaration().DumpStopContext(s, false);
                            s->EOL();
                        }
                    }
                }
            }
        }
        else
        {
            if (fallback_style != DumpStyleInvalid)
                return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
            return false;
        }
        break;
    case DumpStyleResolvedPointerDescription:
        {
            Process *process = exe_ctx.GetProcessPtr();
            if (process)
            {
                addr_t load_addr = GetLoadAddress (target);
                if (load_addr != LLDB_INVALID_ADDRESS)
                {
                    Error memory_error;
                    addr_t dereferenced_load_addr = process->ReadPointerFromMemory(load_addr, memory_error);
                    if (dereferenced_load_addr != LLDB_INVALID_ADDRESS)
                    {
                        Address dereferenced_addr;
                        if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr, target))
                        {
                            StreamString strm;
                            if (dereferenced_addr.Dump (&strm, exe_scope, DumpStyleResolvedDescription, DumpStyleInvalid, addr_size))
                            {
                                s->Address (dereferenced_load_addr, addr_size, " -> ", " ");
                                s->Write(strm.GetData(), strm.GetSize());
                                return true;
                            }
                        }
                    }
                }
            }
            if (fallback_style != DumpStyleInvalid)
                return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
            return false;
        }
        break;
    }

    return true;
}
예제 #23
0
파일: SBFrame.cpp 프로젝트: filcab/lldb
SBValueList
SBFrame::GetVariables (bool arguments,
                       bool locals,
                       bool statics,
                       bool in_scope_only,
                       lldb::DynamicValueType  use_dynamic)
{
    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBValueList value_list;
    Mutex::Locker api_locker;
    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);

    StackFrame *frame = NULL;
    Target *target = exe_ctx.GetTargetPtr();

    if (log)
        log->Printf ("SBFrame::GetVariables (arguments=%i, locals=%i, statics=%i, in_scope_only=%i)", 
                     arguments,
                     locals,
                     statics,
                     in_scope_only);
    
    Process *process = exe_ctx.GetProcessPtr();
    if (target && process)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process->GetRunLock()))
        {
            frame = exe_ctx.GetFramePtr();
            if (frame)
            {
                size_t i;
                VariableList *variable_list = NULL;
                variable_list = frame->GetVariableList(true);
                if (variable_list)
                {
                    const size_t num_variables = variable_list->GetSize();
                    if (num_variables)
                    {
                        for (i = 0; i < num_variables; ++i)
                        {
                            VariableSP variable_sp (variable_list->GetVariableAtIndex(i));
                            if (variable_sp)
                            {
                                bool add_variable = false;
                                switch (variable_sp->GetScope())
                                {
                                case eValueTypeVariableGlobal:
                                case eValueTypeVariableStatic:
                                    add_variable = statics;
                                    break;

                                case eValueTypeVariableArgument:
                                    add_variable = arguments;
                                    break;

                                case eValueTypeVariableLocal:
                                    add_variable = locals;
                                    break;

                                default:
                                    break;
                                }
                                if (add_variable)
                                {
                                    if (in_scope_only && !variable_sp->IsInScope(frame))
                                        continue;

                                    ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable (variable_sp, eNoDynamicValues));
                                    SBValue value_sb;
                                    value_sb.SetSP(valobj_sp,use_dynamic);
                                    value_list.Append(value_sb);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                if (log)
                    log->Printf ("SBFrame::GetVariables () => error: could not reconstruct frame object for this SBFrame.");
            }
        }
        else
        {
            if (log)
                log->Printf ("SBFrame::GetVariables () => error: process is running");
        }            
    }

    if (log)
    {
        log->Printf ("SBFrame(%p)::GetVariables (...) => SBValueList(%p)", frame,
                     value_list.get());
    }

    return value_list;
}
예제 #24
0
Error
IRExecutionUnit::DisassembleFunction (Stream &stream,
                                      lldb::ProcessSP &process_wp)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));

    ExecutionContext exe_ctx(process_wp);

    Error ret;

    ret.Clear();

    lldb::addr_t func_local_addr = LLDB_INVALID_ADDRESS;
    lldb::addr_t func_remote_addr = LLDB_INVALID_ADDRESS;

    for (JittedFunction &function : m_jitted_functions)
    {
        if (strstr(function.m_name.c_str(), m_name.AsCString()))
        {
            func_local_addr = function.m_local_addr;
            func_remote_addr = function.m_remote_addr;
        }
    }

    if (func_local_addr == LLDB_INVALID_ADDRESS)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't find function %s for disassembly", m_name.AsCString());
        return ret;
    }

    if (log)
        log->Printf("Found function, has local address 0x%" PRIx64 " and remote address 0x%" PRIx64, (uint64_t)func_local_addr, (uint64_t)func_remote_addr);

    std::pair <lldb::addr_t, lldb::addr_t> func_range;

    func_range = GetRemoteRangeForLocal(func_local_addr);

    if (func_range.first == 0 && func_range.second == 0)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't find code range for function %s", m_name.AsCString());
        return ret;
    }

    if (log)
        log->Printf("Function's code range is [0x%" PRIx64 "+0x%" PRIx64 "]", func_range.first, func_range.second);

    Target *target = exe_ctx.GetTargetPtr();
    if (!target)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorString("Couldn't find the target");
        return ret;
    }

    lldb::DataBufferSP buffer_sp(new DataBufferHeap(func_range.second, 0));

    Process *process = exe_ctx.GetProcessPtr();
    Error err;
    process->ReadMemory(func_remote_addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), err);

    if (!err.Success())
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Couldn't read from process: %s", err.AsCString("unknown error"));
        return ret;
    }

    ArchSpec arch(target->GetArchitecture());

    const char *plugin_name = NULL;
    const char *flavor_string = NULL;
    lldb::DisassemblerSP disassembler_sp = Disassembler::FindPlugin(arch, flavor_string, plugin_name);

    if (!disassembler_sp)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorStringWithFormat("Unable to find disassembler plug-in for %s architecture.", arch.GetArchitectureName());
        return ret;
    }

    if (!process)
    {
        ret.SetErrorToGenericError();
        ret.SetErrorString("Couldn't find the process");
        return ret;
    }

    DataExtractor extractor(buffer_sp,
                            process->GetByteOrder(),
                            target->GetArchitecture().GetAddressByteSize());

    if (log)
    {
        log->Printf("Function data has contents:");
        extractor.PutToLog (log,
                            0,
                            extractor.GetByteSize(),
                            func_remote_addr,
                            16,
                            DataExtractor::TypeUInt8);
    }

    disassembler_sp->DecodeInstructions (Address (func_remote_addr), extractor, 0, UINT32_MAX, false, false);

    InstructionList &instruction_list = disassembler_sp->GetInstructionList();
    instruction_list.Dump(&stream, true, true, &exe_ctx);
    
    // FIXME: The DisassemblerLLVMC has a reference cycle and won't go away if it has any active instructions.
    // I'll fix that but for now, just clear the list and it will go away nicely.
    disassembler_sp->GetInstructionList().Clear();
    return ret;
}
예제 #25
0
파일: SBFrame.cpp 프로젝트: filcab/lldb
SBValue
SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic)
{
    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    VariableSP var_sp;
    SBValue sb_value;

    if (name == NULL || name[0] == '\0')
    {
        if (log)
            log->Printf ("SBFrame::FindVariable called with empty name");
        return sb_value;
    }
    
    ValueObjectSP value_sp;
    Mutex::Locker api_locker;
    ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);

    StackFrame *frame = NULL;
    Target *target = exe_ctx.GetTargetPtr();
    Process *process = exe_ctx.GetProcessPtr();
    if (target && process)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process->GetRunLock()))
        {
            frame = exe_ctx.GetFramePtr();
            if (frame)
            {
                VariableList variable_list;
                SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock));

                if (sc.block)
                {
                    const bool can_create = true;
                    const bool get_parent_variables = true;
                    const bool stop_if_block_is_inlined_function = true;
                    
                    if (sc.block->AppendVariables (can_create, 
                                                   get_parent_variables,
                                                   stop_if_block_is_inlined_function,
                                                   &variable_list))
                    {
                        var_sp = variable_list.FindVariable (ConstString(name));
                    }
                }

                if (var_sp)
                {
                    value_sp = frame->GetValueObjectForFrameVariable(var_sp, eNoDynamicValues);
                    sb_value.SetSP(value_sp, use_dynamic);
                }
            }
            else
            {
                if (log)
                    log->Printf ("SBFrame::FindVariable () => error: could not reconstruct frame object for this SBFrame.");
            }
        }
        else
        {
            if (log)
                log->Printf ("SBFrame::FindVariable () => error: process is running");
        }
    }
    
    if (log)
        log->Printf ("SBFrame(%p)::FindVariable (name=\"%s\") => SBValue(%p)", 
                     frame, name, value_sp.get());

    return sb_value;
}
void ProcessSetting
( std::string systemID,
  std::string procName,
  std::string procID,
  vector< VariableInProcess > varsInProcArray,
  vector< ParameterInProcess > paramsInProcArray
)
{
    try
    {
        Process* proc;

        // pick up main system from SpatioStepper
        System* aRootSystem( stepperData->getModel()->getRootSystem() );

        // pick up sub system from main system
        System* aSubSystem( aRootSystem->getSystem( "/Cell0" ) );

        // pick up sub system2 from main system
        System* aSubSystem2( aRootSystem->getSystem( "/Cell1" ) );

        // input original parameters to each Process
        if( !inputOriginalParamsToProcess( proc, procName, paramsInProcArray ) )
            throw std::exception();

        // input common parameters to each Process
        proc->setID( procID );
        proc->setProcessName( procName );
        for( int i = 0; i < ( int )varsInProcArray.size(); i++ )
        {
            std::string name;
            // name is "___XXX" (XXX is Variable number with at least two-digit number.).
            if( i < 10 )
                name = "___0" + boost::lexical_cast<std::string>( i );
            else
                name = "___" + boost::lexical_cast<std::string>( i );

            std::string ID = varsInProcArray[i].getID();
            // If ID doesn't contains ":", input Variable in main system to process.
            if( ID.find( ":", 0 ) == string::npos )
                proc->registerVariableReference( name, aRootSystem->getVariable( ID ), varsInProcArray[i].getCoefficient(), varsInProcArray[i].getAccessor() );
            // Else if ID doesn't contains "Cell1", input Variable in sub system to process.
            else if( ID.find( "Cell1", 0 ) == string::npos )
            {
                ID.erase( 0, ID.find( ":", 0 ) + 1 );
                proc->registerVariableReference( name, aSubSystem->getVariable( ID ), varsInProcArray[i].getCoefficient(), varsInProcArray[i].getAccessor() );
            }
            // Else if ID contains "Cell1", input Variable in sub system2 to process.
            else
            {
                ID.erase( 0, ID.find( ":", 0 ) + 1 );
                proc->registerVariableReference( name, aSubSystem2->getVariable( ID ), varsInProcArray[i].getCoefficient(), varsInProcArray[i].getAccessor() );
            }
        }

        proc->setStepper( stepperData );
        proc->setSuperSystem( aRootSystem );
        proc->preinitialize();
        proc->initialize();

        stepperData->registerProcess( proc );
        if( systemID == "/" )
            aRootSystem->registerEntity( proc );
        else if( systemID == "/Cell0" )
            aSubSystem->registerEntity( proc );
        else
            aSubSystem2->registerEntity( proc );
    }
    catch( std::exception )
    {
        cout << "Invalid process name was input." << endl;
    }
}
예제 #27
0
size_t
UnwindMacOSXFrameBackchain::GetStackFrameData_i386 (const ExecutionContext &exe_ctx)
{
    m_cursors.clear();
    
    StackFrame *first_frame = exe_ctx.GetFramePtr();

    Process *process = exe_ctx.GetProcessPtr();
    if (process == NULL)
        return 0;
    
    std::pair<lldb::addr_t, lldb::addr_t> fp_pc_pair;

    struct Frame_i386
    {
        uint32_t fp;
        uint32_t pc;
    };

    RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
    assert (reg_ctx);

    Cursor cursor;
    cursor.pc = reg_ctx->GetPC (LLDB_INVALID_ADDRESS);
    cursor.fp = reg_ctx->GetFP (0);
    
    Frame_i386 frame = { static_cast<uint32_t>(cursor.fp), static_cast<uint32_t>(cursor.pc) };

    m_cursors.push_back(cursor);

    const size_t k_frame_size = sizeof(frame);
    Error error;
    while (frame.fp != 0 && frame.pc != 0 && ((frame.fp & 7) == 0))
    {
        // Read both the FP and PC (8 bytes)
        if (process->ReadMemory (frame.fp, &frame.fp, k_frame_size, error) != k_frame_size)
            break;
        if (frame.pc >= 0x1000)
        {
            cursor.pc = frame.pc;
            cursor.fp = frame.fp;
            m_cursors.push_back (cursor);
        }
    }
    if (!m_cursors.empty())
    {
        lldb::addr_t first_frame_pc = m_cursors.front().pc;
        if (first_frame_pc != LLDB_INVALID_ADDRESS)
        {
            const uint32_t resolve_scope = eSymbolContextModule |
                                           eSymbolContextCompUnit |
                                           eSymbolContextFunction |
                                           eSymbolContextSymbol;

            SymbolContext first_frame_sc (first_frame->GetSymbolContext(resolve_scope));
            const AddressRange *addr_range_ptr = NULL;
            AddressRange range;
            if (first_frame_sc.function)
                addr_range_ptr = &first_frame_sc.function->GetAddressRange();
            else if (first_frame_sc.symbol)
            {
                range.GetBaseAddress() = first_frame_sc.symbol->GetAddress();
                range.SetByteSize (first_frame_sc.symbol->GetByteSize());
                addr_range_ptr = &range;
            }

            if (addr_range_ptr)
            {
                if (first_frame->GetFrameCodeAddress() == addr_range_ptr->GetBaseAddress())
                {
                    // We are at the first instruction, so we can recover the
                    // previous PC by dereferencing the SP
                    lldb::addr_t first_frame_sp = reg_ctx->GetSP (0);
                    // Read the real second frame return address into frame.pc
                    if (first_frame_sp && process->ReadMemory (first_frame_sp, &frame.pc, sizeof(frame.pc), error) == sizeof(frame.pc))
                    {
                        cursor.fp = m_cursors.front().fp;
                        cursor.pc = frame.pc;           // Set the new second frame PC

                        // Insert the second frame
                        m_cursors.insert(m_cursors.begin()+1, cursor);
                        
                        m_cursors.front().fp = first_frame_sp;
                    }
                }
            }
        }
    }
//    uint32_t i=0;
//    printf("      PC                 FP\n");
//    printf("      ------------------ ------------------ \n");
//    for (i=0; i<m_cursors.size(); ++i)
//    {
//        printf("[%3u] 0x%16.16llx 0x%16.16llx\n", i, m_cursors[i].pc, m_cursors[i].fp);
//    }
    return m_cursors.size();
}
예제 #28
0
void ObjectMemory::FixupObject(OTE* ote, MWORD* oldLocation, const ImageHeader* pHeader)
{
	// Convert the class now separately
	BehaviorOTE* classPointer = reinterpret_cast<BehaviorOTE*>(FixupPointer(reinterpret_cast<OTE*>(ote->m_oteClass), static_cast<OTE*>(pHeader->BasePointer)));
#ifdef _DEBUG
	{
		PointersOTE* oteObj = reinterpret_cast<PointersOTE*>(ote);
		if (ote->isPointers() && (oteObj->getSize() % 2 == 1 ||
			classPointer == _Pointers.ClassByteArray ||
			classPointer == _Pointers.ClassAnsiString ||
			classPointer == _Pointers.ClassUtf8String ||
			classPointer == _Pointers.ClassSymbol))
		{
			TRACESTREAM<< L"Bad OTE for byte array " << LPVOID(&ote)<< L" marked as pointer" << std::endl;
			ote->beBytes();
		}
	}
#endif

	ote->m_oteClass = classPointer;

	if (ote->isPointers())
	{
		PointersOTE* otePointers = reinterpret_cast<PointersOTE*>(ote);
		VariantObject* obj = otePointers->m_location;

		const SMALLUNSIGNED numFields = ote->pointersSize();
		ASSERT(SMALLINTEGER(numFields) >= 0);
		// Fixup all the Oops
		for (SMALLUNSIGNED i = 0; i < numFields; i++)
		{
			Oop instPointer = obj->m_fields[i];
			if (!isIntegerObject(instPointer))
				obj->m_fields[i] = Oop(FixupPointer(reinterpret_cast<OTE*>(instPointer), static_cast<OTE*>(pHeader->BasePointer)));
		}

		if (classPointer == _Pointers.ClassProcess)
		{
			Process* process = static_cast<Process*>(ote->m_location);
			// We use the callbackDepth slot to store the delta in location
			// which we later use to adjust all the stack references.
			// The previous value is lost, but this is not important
			// as it must be reestablished as zero anyway
			process->BasicSetCallbackDepth(Oop(process) - Oop(oldLocation) + 1);
		}
		// else
		// MethodContext objects contain a pointer to their frame in the
		// stack, but we must fix that up later when walking down the stack.
	}
	else
	{
		if (classPointer == _Pointers.ClassExternalHandle)
		{
			// In Dolphin 4.0, all ExternalHandles are automatically nulled
			// on image load.

			ExternalHandle* handle = static_cast<ExternalHandle*>(ote->m_location);
			handle->m_handle = NULL;
		}
		// Look for the special image stamp object
		else if (classPointer == _Pointers.ClassContext)
		{
			ASSERT(ote->heapSpace() == OTEFlags::PoolSpace || ote->heapSpace() == OTEFlags::NormalSpace);

			// Can't deallocate now - must leave for collection later - maybe could go in the Zct though.
			VERIFY(ote->decRefs());
			deallocate(reinterpret_cast<OTE*>(ote));
		}
	}
}
예제 #29
0
파일: Process.cpp 프로젝트: terranpro/rct
void ProcessThread::run()
{
    pid_t pid;
    char* buf = reinterpret_cast<char*>(&pid);
    ssize_t hasread = 0, r;
    for (;;) {
        //printf("reading pid (%lu remaining)\n", sizeof(pid_t) - hasread);
        r = ::read(sProcessPipe[0], &buf[hasread], sizeof(pid_t) - hasread);
        //printf("did read %ld\n", r);
        if (r >= 0)
            hasread += r;
        else {
            if (errno != EINTR) {
                error() << "ProcessThread is dying, errno " << errno << " strerror " << strerror(errno);
                break;
            }
        }
        if (hasread == sizeof(pid_t)) {
            //printf("got a full pid %d\n", pid);
            if (pid == 0) { // if our pid is 0 due to siginfo_t having an invalid si_pid then we have a misbehaving kernel.
                // regardless, we need to go through all children and call a non-blocking waitpid on each of them
                int ret;
                pid_t p;
                std::unique_lock<std::mutex> lock(sProcessMutex);
                std::map<pid_t, Process*>::iterator proc = sProcesses.begin();
                const std::map<pid_t, Process*>::const_iterator end = sProcesses.end();
                while (proc != end) {
                    //printf("testing pid %d\n", proc->first);
                    p = ::waitpid(proc->first, &ret, WNOHANG);
                    switch(p) {
                    case 0:
                    case -1:
                        //printf("this is not the pid I'm looking for\n");
                        ++proc;
                        break;
                    default:
                        //printf("successfully waited for pid (got %d)\n", p);
                        if (WIFEXITED(ret))
                            ret = WEXITSTATUS(ret);
                        else
                            ret = -1;
                        Process *process = proc->second;
                        sProcesses.erase(proc++);
                        lock.unlock();
                        process->finish(ret);
                        lock.lock();
                    }
                }
            } else if (pid == 1) { // stopped
                break;
            } else {
                int ret;
                //printf("blocking wait pid %d\n", pid);
                ::waitpid(pid, &ret, 0);
                //printf("wait complete\n");
                Process *process = 0;
                {
                    std::lock_guard<std::mutex> lock(sProcessMutex);
                    std::map<pid_t, Process*>::iterator proc = sProcesses.find(pid);
                    if (proc != sProcesses.end()) {
                        if (WIFEXITED(ret))
                            ret = WEXITSTATUS(ret);
                        else
                            ret = -1;
                        process = proc->second;
                        sProcesses.erase(proc);
                    }
                }
                if (process)
                    process->finish(ret);
            }
            hasread = 0;
        }
    }
    debug() << "ProcessThread dead";
    //printf("process thread died for some reason\n");
}
예제 #30
0
//
// Perform legacy hash verification.
// This is the pre-Leopard (Tiger, Panther) code path. Here we only have legacy hashes
// (called, confusingly, "signatures"), which we're matching against suitably computed
// "signatures" (hashes) on the requesting application. We consult the CodeEquivalenceDatabase
// in a doomed attempt to track changes made to applications through updates, and issue
// equivalence dialogs to users if we have a name match (but hash mismatch). That's all
// there was before Code Signing; and that's what you'll continue to get if the requesting
// application is unsigned. Until we throw the whole mess out altogether, hopefully by
// the Next Big Cat After Leopard.
//
bool CodeSignatures::verifyLegacy(Process &process, const CssmData &signature, string path)
{
	// First of all, if the signature directly matches the client's code, we're obviously fine
	// we don't even need the database for that...
	Identity &clientIdentity = process;
	try {
		if (clientIdentity.getHash() == signature) {
			secdebug("codesign", "direct match: pass");
			return true;
		}
	} catch (...) {
		secdebug("codesign", "exception getting client code hash: fail");
		return false;
	}
	
#if CONSULT_LEGACY_CODE_EQUIVALENCE_DATABASE
	
	// Ah well. Establish mediator objects for database signature links
	AclIdentity aclIdentity(signature, path);

	uid_t user = process.uid();
	{
		StLock<Mutex> _(mDatabaseLock);
		find(aclIdentity, user);
		find(clientIdentity, user);
	}

	// if both links exist, we can decide this right now
	if (aclIdentity && clientIdentity) {
		if (aclIdentity.trustedName() == clientIdentity.trustedName()) {
			secdebug("codesign", "app references match: pass");
			return true;
		} else {
			secdebug("codesign", "client/acl links exist but are unequal: fail");
			return false;
		}
	}
	
	// check for name equality
	secdebug("codesign", "matching client %s against acl %s",
		clientIdentity.name().c_str(), aclIdentity.name().c_str());
	if (aclIdentity.name() != clientIdentity.name()) {
		secdebug("codesign", "name/path mismatch: fail");
		return false;
	}
	
	// The names match - we have a possible update.
	
	// Take the UI lock now to serialize "update rushes".
	LongtermStLock uiLocker(mUILock);
	
	// re-read the database in case some other thread beat us to the update
	{
		StLock<Mutex> _(mDatabaseLock);
		find(aclIdentity, user);
		find(clientIdentity, user);
	}
	if (aclIdentity && clientIdentity) {
		if (aclIdentity.trustedName() == clientIdentity.trustedName()) {
			secdebug("codesign", "app references match: pass (on the rematch)");
			return true;
		} else {
			secdebug("codesign", "client/acl links exist but are unequal: fail (on the rematch)");
			return false;
		}
	}
	
	// ask the user
	QueryCodeCheck query;
    query.inferHints(process);
	if (!query(aclIdentity.path().c_str()))
    {
		secdebug("codesign", "user declined equivalence: cancel the access");
		CssmError::throwMe(CSSM_ERRCODE_USER_CANCELED);
	}

	// take the database lock back for real
	StLock<Mutex> _(mDatabaseLock);
	
	// user wants us to go ahead and establish trust (if possible)
	if (aclIdentity) {
		// acl is linked but new client: link the client to this application
		makeLink(clientIdentity, aclIdentity.trustedName(), true, user);
		mDb.flush();
		secdebug("codesign", "client %s linked to application %s: pass",
			clientIdentity.path().c_str(), aclIdentity.trustedName().c_str());
		return true;
	}
	
	if (clientIdentity) {	// code link exists, acl link missing
		// client is linked but ACL (hash) never seen: link the ACL to this app
		makeLink(aclIdentity, clientIdentity.trustedName(), true, user);
		mDb.flush();
		secdebug("codesign", "acl %s linked to client %s: pass",
			aclIdentity.path().c_str(), clientIdentity.trustedName().c_str());
		return true;
	}
	
	// the De Novo case: no links, must create everything
	string ident = clientIdentity.name();
	makeLink(clientIdentity, ident, true, user);
	makeLink(aclIdentity, ident, true, user);
	mDb.flush();
	secdebug("codesign", "new linkages established: pass");
	return true;

#else /* ignore Code Equivalence Database */

	return false;

#endif
}