⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread-packets.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    return threadref_to_int(&thread) ;
  else
    return 0 ;
}

void stub_pkt_currthread(
                                char * inbuf,
                                char * outbuf,
                                int bufmax)
{
  threadref thread ;
  char * base_out ;
  base_out = outbuf ;
  
  if (dbg_currthread(&thread))
    {
      *outbuf++ = 'Q' ;
      *outbuf++ = 'C' ; /* FIXME: Is this a reasonable code */
      outbuf = pack_int(outbuf, threadref_to_int(&thread)) ; /* Short form */
    }
  else outbuf = stub_pack_nak(outbuf) ;
  *outbuf = '\0' ; /* terminate response packet */
  PKT_TRACE("stub_pkt_currthread(resp) ",base_out) ;
} /* stub_pkt_currthread */

/* ----- STUB_PKT_THREAD_ALIVE --------------------------------- */
/* Answer the thread alive query */

static int thread_alive (int id)
{
  threadref thread ;
  struct cygmon_thread_debug_info info ;

  int_to_threadref(&thread, id) ;
  if (dbg_threadinfo(&thread, &info) &&
      info.context_exists)
    return 1 ;
  else
    return 0 ;
}

void stub_pkt_thread_alive(char * inbuf,
                           char * outbuf,
                           int bufmax)
{
  char * prebuf = inbuf ;
  int result ;
  
  if (prebuf != (inbuf = unpack_varlen_hex(inbuf,&result)))
    {
      if (thread_alive(result))
        {
          outbuf = stub_pack_ack(outbuf) ;
          *outbuf = '\0' ;
          return ;
        }
    }
  outbuf = stub_pack_nak(outbuf) ;
  *outbuf = '\0' ; /* terminate the response message */
} /* stub_pkt_thread_alive */

 

/* ----- STUB_PKT_CHANGETHREAD ------------------------------- */
/* Switch the display of registers to that of a saved context */

/* Changing the context makes NO sense, although the packets define the
   capability. Therefore, the option to change the context back does
   call the function to change registers. Also, there is no
   forced context switch.
     'p' - New format, long long threadid, no special cases
     'c' - Old format, id for continue, 32 bit threadid max, possably less
                       -1 means continue all threads
     'g' - Old Format, id for general use (other than continue)

     replies:
          OK for success
          ENN for error
   */

void stub_pkt_changethread(
                           char * inbuf,
                           char * outbuf,
                           int bufmax)
{
  threadref id ;
  int idefined = -1 ;
  char ch ;
  PKT_TRACE("setthread-pkt ",inbuf) ;

  /* Parse the incoming packet for a thread identifier */
  switch (ch = *inbuf++ )  /* handle various packet formats */
    {
    case 'p' : /* New format: mode:8,threadid:64 */
      inbuf = unpack_nibble(inbuf,&idefined) ;
      inbuf = unpack_threadid(inbuf,&id) ; /* even if startflag */
      break ;  
    case 'c' : /* old format , specify thread for continue */
      if (inbuf[0] == '-' && inbuf[1] == '1')   /* Hc-1 */
        _gdb_cont_thread = 0 ;
      else
        inbuf = unpack_varlen_hex(inbuf, &_gdb_cont_thread) ;

      if (_gdb_cont_thread == 0 ||              /* revert to any old thread */
          thread_alive(_gdb_cont_thread))       /* specified thread is alive */
        outbuf = stub_pack_ack(outbuf) ;
      else
        outbuf = stub_pack_nak(outbuf) ;
      break ;
    case 'g' : /* old format, specify thread for general operations */
      /* OLD format: parse a variable length hex string */
      /* OLD format consider special thread ids */
      {
        inbuf = unpack_varlen_hex(inbuf, &_gdb_general_thread) ;
        int_to_threadref(&id, _gdb_general_thread) ;
        switch (_gdb_general_thread)
          {
          case  0 : /* pick a thread, any thread */
            idefined = 2 ; /* select original interrupted context */
            break ;
          case -1 : /* all threads */
            idefined = 2 ;
            break ;
          default :
            idefined = 1 ; /* select the specified thread */
            break ;
          }
      }
      break ;
    default:
      outbuf = stub_pack_nak(outbuf) ;
      break ;
    } /* handle various packet formats */

  switch (idefined)
    {
    case -1 :
      /* Packet not supported, already NAKed, no further action */
      break ;
    case 0 :
      /* Switch back to interrupted context */
      _registers = &registers[0] ;
      break ;
    case 1 :
      /* copy the saved registers into the backup registers */
      stub_copy_registers(alt_registers,registers) ;
      /* The OS will now update the values it has in a saved process context*/
      if (dbg_getthreadreg(&id,NUMREGS,&alt_registers[0]))
        {
          /* switch the registers pointer */
          _registers = &alt_registers[0] ;
          outbuf = stub_pack_ack(outbuf) ; 
        }
      else
          outbuf = stub_pack_nak(outbuf) ;
      break ;
    case 2 :
      /* switch to interrupted context */ 
      outbuf = stub_pack_ack(outbuf) ;
      break ;
    default:
      outbuf = stub_pack_nak(outbuf) ;
      break ;
    }
  *outbuf = '\0' ; /* Terminate response pkt */
} /* stub_pkt_changethread */


/* ---- STUB_PKT_GETTHREADLIST ------------------------------- */
/* Get a portion of the threadlist  or process list            */
/* This may be part of a multipacket transaction               */
/* It would be hard to tell in the response packet the difference
   between the end of list and an error in threadid encoding.
   */

void stub_pkt_getthreadlist(char * inbuf,
                            char * outbuf,
                            int bufmax)
{
  char * count_ptr ;
  char * done_ptr ;
  char * limit ;
  int start_flag , batchsize , result , count ;
  static threadref lastthread, nextthread ;

#if PKT_DEBUG
  char * r_base = outbuf ;
#endif  
  PKT_TRACE("pkt_getthreadlist: ",inbuf) ;

  count = 0 ;
  inbuf = unpack_nibble(inbuf,&start_flag) ;
  inbuf = unpack_byte(inbuf,&batchsize) ;
  inbuf = unpack_threadid(inbuf,&lastthread) ; /* even if startflag */

  /*   Start building response packet    */
  limit = outbuf + (bufmax - BUFTHREADIDSIZ - 10) ; /* id output packing limit */
  *outbuf++ = 'Q'  ;
  *outbuf++ = 'M'  ;
  
  /* Default values for count and done fields, save ptr to repatch */
  count_ptr = outbuf ; /* save to repatch count */
  outbuf = pack_hex_byte(outbuf,0) ;
  done_ptr = outbuf ;  /* Backpatched later */
  *outbuf++ = '0' ;    /* Done = 0 by default */
  outbuf = pack_threadid(outbuf,&lastthread) ;
  
  /* Loop through the threadid packing */
  while ((outbuf < limit) && (count < batchsize))
    {
      result = dbg_threadlist(start_flag,&lastthread,&nextthread) ;
      start_flag = 0 ; /* redundant but effective */
      if (!result)
        { *done_ptr = '1' ;   /* pack the done flag */
          break ;
        }
#if 0 /* DEBUG */
      if (threadmatch(&lastthread,&nextthread))
        {
          output_string("FAIL: Threadlist, not incrementing\n") ;
          *done_ptr = '1' ;
          break ;
        }
#endif      
      count++ ;
      outbuf = pack_threadid(outbuf,&nextthread) ;
      copy_threadref(&lastthread,&nextthread) ;
    }
  pack_hex_byte(count_ptr,count) ;/* backpatch, Pack the count field */
  *outbuf = '\0' ;
  PKT_TRACE("pkt_getthreadlist(resp) ",r_base) ;
} /* pkt_getthreadlist */




/* ----- STUB_PKT_GETTHREADINFO ---------------------------------------- */
/* Get the detailed information about a specific thread or process */

/*
Encoding:
 'Q':8,'P':8,mask:16

 Mask Fields
        threadid:1,        # always request threadid 
        context_exists:2,
        display:4,          
        unique_name:8,
        more_display:16
 */  

void stub_pkt_getthreadinfo(
                            char * inbuf,
                            char * outbuf,
                            int bufmax)
{
  int mask ;
  int result ;
  threadref thread ;
  struct cygmon_thread_debug_info info ;

  info.context_exists = 0 ;
  info.thread_display = 0 ;
  info.unique_thread_name = 0 ;
  info.more_display = 0 ;

  /* Assume the packet identification chars have already been
     discarded by the packet demultiples routines */
  PKT_TRACE("PKT getthreadinfo",inbuf) ;
  
  inbuf = unpack_int(inbuf,&mask) ;
  inbuf = unpack_threadid(inbuf,&thread) ;
  
  result = dbg_threadinfo(&thread,&info) ; /* Make system call */

  if (result)
    {
      *outbuf++ = 'q' ;
      *outbuf++ = 'p' ;
      outbuf = pack_int(outbuf,mask) ;
      outbuf = pack_threadid(outbuf,&info.thread_id) ; /* echo threadid */
      if (mask & 2)   /* context-exists */
        {
          outbuf = pack_int(outbuf,2) ; /* tag */
          outbuf = pack_hex_byte(outbuf,2) ; /* length */
          outbuf = pack_hex_byte(outbuf,info.context_exists) ;
        }
      if ((mask & 4)  && info.thread_display)/* display */
        {
          outbuf = pack_int(outbuf,4) ; /* tag */
          outbuf = pack_string(outbuf,info.thread_display) ;
        }
      if ((mask & 8) && info.unique_thread_name) /* unique_name */
        {
          outbuf = pack_int(outbuf,8) ;
          outbuf = pack_string(outbuf,info.unique_thread_name) ;
        }
      if ((mask & 16) && info.more_display)  /* more display */
        {
          outbuf = pack_int(outbuf,16) ; /* tag 16 */
          outbuf = pack_string(outbuf,info.more_display) ;
        }
    }
  else
    {
      PKT_TRACE("FAIL: dbg_threadinfo\n", "") ;
      outbuf = stub_pack_nak(outbuf) ;
    }
  *outbuf = '\0' ;
} /* stub_pkt_getthreadinfo */

int stub_lock_scheduler(int lock,       /* 0 to unlock, 1 to lock */
                        int mode,       /* 0 for step,  1 for continue */
                        long id)        /* current thread */
{
  threadref thread;

  int_to_threadref(&thread, id) ;
  return dbg_scheduler(&thread, lock, mode) ;
}


#if GDB_MOCKUP
/* ------ MATCHED GDB SIDE PACKET ENCODING AND PARSING ----------------- */

char * pack_nibble(char * buf, int nibble)
{
  *buf++ =  hexchars[(nibble & 0x0f)] ;
  return buf ;
} /* pack_nibble */

#if 0
static char * unpack_short(char * buf,int * value)
{
  *value = stub_unpack_int(buf,4) ;
  return buf + 4 ;
}

static char * pack_short(
                  char * buf,
                  unsigned int value)
{
  buf = pack_hex_byte(buf,(value >> 8) & 0xff) ;
  buf = pack_hex_byte(buf,(value & 0xff)) ;
  return buf ;
} /* pack_short */
#endif


/* Generally, I dont bury xmit and receive calls inside packet formatters
   and parsers
   */




/* ----- PACK_SETTHREAD_REQUEST ------------------------------------- */
/*      Encoding: ??? decode gdb/remote.c
        'Q':8,'p':8,idefined:8,threadid:32 ;
        */

char * pack_setthread_request(
                       char * buf,
                       char fmt,   /* c,g or, p */
                       int idformat ,
                       threadref *  threadid )
{
  *buf++ = fmt ;
  
  if (fmt == 'p')
    {  /* pack the long form */
      buf = pack_nibble(buf,idformat) ;
      buf = pack_threadid(buf,threadid)  ;
    }
  else
    {  /* pack the shorter form - Serious truncation */
      /* There are reserved identifieds 0 , -1 */
      int quickref = threadref_to_int(threadid) ;
      buf = pack_varlen_hex(buf,quickref) ;
    }
  *buf++ = '\0' ; /* end_of_packet  */
  return buf ;
} /* pack_setthread_request */



/* -------- PACK_THREADLIST-REQUEST --------------------------------- */
/*    Format: i'Q':8,i"L":8,initflag:8,batchsize:16,lastthreadid:32   */


char * pack_threadlist_request(
                               char * pkt,
                               int startflag,
                               int threadcount,
                               threadref * nextthread 
                               )
{
  *pkt++ = 'q' ;
  *pkt++ = 'L' ;
  pkt = pack_nibble(pkt,startflag) ;     /* initflag 1 bytes */
  pkt = pack_hex_byte(pkt,threadcount) ;   /* threadcount 2 bytes */
  pkt = pack_threadid(pkt,nextthread) ;        /* 64 bit thread identifier */
  *pkt = '\0' ;
  return pkt ;
} /* remote_threadlist_request */




/* ---------- PARSE_THREADLIST_RESPONSE ------------------------------------ */
/* Encoding:   'q':8,'M':8,count:16,done:8,argthreadid:64,(threadid:64)* */

int parse_threadlist_response(
                              char * pkt,
                              threadref * original_echo,
                              threadref * resultlist,
                              int * doneflag)
{
  char * limit ;
  int count, resultcount , done ;
  resultcount = 0 ;

  /* assume the 'q' and 'M chars have been stripped */
  PKT_TRACE("parse-threadlist-response ",pkt) ;
  limit = pkt + (STUB_BUF_MAX - BUFTHREADIDSIZ) ; /* done parse past here */
  pkt = unpack_byte(pkt,&count)  ;                /* count field */
  pkt = unpack_nibble(pkt,&done) ;
  /* The first threadid is the argument threadid */
  pkt = unpack_threadid(pkt,original_echo) ; /* should match query packet */
  while ((count-- > 0) && (pkt < limit))
    {
      pkt = unpack_threadid(pkt,resultlist++) ;
      resultcount++ ;
    }
  if (doneflag) *doneflag = done ;
  return resultcount ; /* successvalue */
} /* parse_threadlist_response */
 
struct gdb_ext_thread_info
{
  threadref threadid ;
  int active ;
  char display[256] ;
  char shortname[32] ;
  char more_display[256] ;
} ;


/* ----- PACK_THREAD_INFO_REQUEST -------------------------------- */

/* 
   threadid:1,        # always request threadid
   context_exists:2,
   display:4,
   unique_name:8,
   more_display:16
 */

/* Encoding:  'Q':8,'P':8,mask:32,threadid:64 */

char * pack_threadinfo_request(char * pkt,
                                int mode,
                                threadref * id 
                                )
{
  *pkt++ = 'Q' ;
  *pkt++ = 'P' ;
  pkt = pack_int(pkt,mode) ; /* mode */
  pkt = pack_threadid(pkt,id) ; /* threadid */
  *pkt = '\0' ; /* terminate */
  return pkt ;
} /* pack_thread_info_request */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -