Beispiel #1
0
static void relocateX86_64(struct elf_obj *elfobj,
                           void *(*find_sym)(void *context, char const *name),
                           void *context,
                           struct elf_sec *reltab,
                           unsigned char *text)
{
    int idx, i, reltab_size;
    struct elf_sym *symtab, *sym_entry;
    ELF_RELOC *rel_tablep, *rel_entry;
    int32_t *inst, P, A, S;

    idx = -1;
    get_idxorname(elfobj, ".symtab", &idx);
    if (idx < 0) {
        HSA_DEBUG_LOG(".symtab can't find.\n");
        isfailed = 1;
        return;
    }
    symtab = (struct elf_sym *)(elfobj->sec_tablep[idx].buf);

    reltab_size = (int)(unsigned long)reltab->extra;
    rel_tablep = (ELF_RELOC *)reltab->buf;
    for (i = 0; i < reltab_size; i++) {
        rel_entry = &rel_tablep[i];
        sym_entry = &symtab[ELF_R_SYM(rel_entry->r_info)];

        inst = (int32_t *)&(text[rel_entry->r_offset]);
        P = (int32_t)(int64_t)inst;
        A = (int32_t)(int64_t)rel_entry->r_addend;
        S = (int32_t)(int64_t)get_symety_addr(elfobj, sym_entry, 1);

        if (0 == S) {
            S = (int64_t)find_sym(context, get_symname(elfobj, sym_entry));
            /* zdguo: set the S to the symbol entry struct for optimization */
        }

        switch (ELF_R_TYPE(rel_entry->r_info)) {
        case R_X86_64_64:
            *inst = (S+A);
            break;
        case R_X86_64_PC32:
            *inst = (S+A-P);
            break;
        case R_X86_64_32:
        case R_X86_64_32S:
            *inst = (S+A);
            break;
        default:
            HSA_DEBUG_LOG("Not implemented relocation type.\n");
            isfailed = 1;
            break;
        }
    }

    return;
}
Beispiel #2
0
void list_for(char *var, statement *stmt)
{
  char *tmp1 = 0, *tmp2 = 0, *tmp3 = 0;

  mysprintf(var, "%s=", get_symname(stmt->metalist[1].shortarg));
  simplifylist(var, stmt, 2, stmt->metapos);

  if (outcount == 3) {
    tmp3 = listpop();
    tmp2 = listpop();
    tmp1 = listpop();
  } else {
    tmp2 = listpop();
    tmp1 = listpop();
  }    
  mysprintf(var, "%s TO %s", tmp1, tmp2);
  if (tmp3) mysprintf(var, " STEP %s", tmp3);
}
Beispiel #3
0
struct token *
lr_token (struct linereader *lr, const struct charmap_t *charmap,
	  struct localedef_t *locale, const struct repertoire_t *repertoire,
	  int verbose)
{
  int ch;

  while (1)
    {
      do
	{
	  ch = lr_getc (lr);

	  if (ch == EOF)
	    {
	      lr->token.tok = tok_eof;
	      return &lr->token;
	    };

	  if (ch == '\n')
	    {
	      lr->token.tok = tok_eol;
	      return &lr->token;
	    }
	}
      while (isspace (ch));

      if (ch != lr->comment_char)
	break;

      /* Is there an newline at the end of the buffer?  */
      if (lr->buf[lr->bufact - 1] != '\n')
	{
	  /* No.  Some people want this to mean that only the line in
	     the file not the logical, concatenated line is ignored.
	     Let's try this.  */
	  lr->idx = lr->bufact;
	  continue;
	}

      /* Ignore rest of line.  */
      lr_ignore_rest (lr, 0);
      lr->token.tok = tok_eol;
      return &lr->token;
    }

  /* Match escape sequences.  */
  if (ch == lr->escape_char)
    return get_toplvl_escape (lr);

  /* Match ellipsis.  */
  if (ch == '.')
    {
      if (strncmp (&lr->buf[lr->idx], "...(2)....", 10) == 0)
	{
	  int cnt;
	  for (cnt = 0; cnt < 10; ++cnt)
	    lr_getc (lr);
	  lr->token.tok = tok_ellipsis4_2;
	  return &lr->token;
	}
      if (strncmp (&lr->buf[lr->idx], "...", 3) == 0)
	{
	  lr_getc (lr);
	  lr_getc (lr);
	  lr_getc (lr);
	  lr->token.tok = tok_ellipsis4;
	  return &lr->token;
	}
      if (strncmp (&lr->buf[lr->idx], "..", 2) == 0)
	{
	  lr_getc (lr);
	  lr_getc (lr);
	  lr->token.tok = tok_ellipsis3;
	  return &lr->token;
	}
      if (strncmp (&lr->buf[lr->idx], ".(2)..", 6) == 0)
	{
	  int cnt;
	  for (cnt = 0; cnt < 6; ++cnt)
	    lr_getc (lr);
	  lr->token.tok = tok_ellipsis2_2;
	  return &lr->token;
	}
      if (lr->buf[lr->idx] == '.')
	{
	  lr_getc (lr);
	  lr->token.tok = tok_ellipsis2;
	  return &lr->token;
	}
    }

  switch (ch)
    {
    case '<':
      return get_symname (lr);

    case '0' ... '9':
      lr->token.tok = tok_number;
      lr->token.val.num = ch - '0';

      while (isdigit (ch = lr_getc (lr)))
	{
	  lr->token.val.num *= 10;
	  lr->token.val.num += ch - '0';
	}
      if (isalpha (ch))
	lr_error (lr, _("garbage at end of number"));
      lr_ungetn (lr, 1);

      return &lr->token;

    case ';':
      lr->token.tok = tok_semicolon;
      return &lr->token;

    case ',':
      lr->token.tok = tok_comma;
      return &lr->token;

    case '(':
      lr->token.tok = tok_open_brace;
      return &lr->token;

    case ')':
      lr->token.tok = tok_close_brace;
      return &lr->token;

    case '"':
      return get_string (lr, charmap, locale, repertoire, verbose);

    case '-':
      ch = lr_getc (lr);
      if (ch == '1')
	{
	  lr->token.tok = tok_minus1;
	  return &lr->token;
	}
      lr_ungetn (lr, 2);
      break;
    }

  return get_ident (lr);
}
Beispiel #4
0
/**
 * @brief Match a function in a symbol table.
 * @param sect Section pointer for symbol table.
 * @param num Element number.
 * @param preg Reguler expression to use.
 * @param func_list Function table.
 * @param count Counter pointer (from the table).
 * @param get_symname Function ptr to get symbol name.
 * @return Success (0) or Error (-1).
 */
static int		trace_match_symtab(elfshsect_t	*sect, 
					   int		num, 
					   regex_t	*preg,
					   char		***func_list, 
					   u_int	*count,
					   char		*(*get_symname)(elfshobj_t *f, 
									elfsh_Sym *s))
{
  u_int			index;
  elfsh_Sym		*table;
  char			*name;
  char			**f_list;
  u_int			cnum;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Check argument before anything */
  if (!sect || !preg || !func_list || !count || !get_symname)
     PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		 "Invalid parameters", -1);

  f_list = *func_list;
  cnum = *count;
  table = (elfsh_Sym *) (sect->shdr->sh_addr ? elfsh_readmem(sect) : sect->data);

  /* Parse every function */
  for (index = 0; index < num; index++)
    {
      /* Only functions */
      if (elfsh_get_symbol_type(table + index) != STT_FUNC
	  || table[index].st_value == 0)
	continue;

      name = get_symname(sect->parent, table + index);

      /* Check if this name is valid */
      if (name == NULL || *name == 0)
	continue;

      /* We match a function */
      if (regexec(preg, name, 0, 0, 0) == 0)
	{
	  /* Do we need to realloc ? */
	  if (((cnum+1) % TRACE_MATCH_ALLOCSTEP) == 0)
	    {
	      XREALLOC(__FILE__, __FUNCTION__, __LINE__, f_list, f_list, 
		       sizeof(char*) * (cnum + 1 + TRACE_MATCH_ALLOCSTEP), -1);

	      /* Blank new elements */
	      memset(&f_list[cnum], 0x00, TRACE_MATCH_ALLOCSTEP*sizeof(char*));

	      /* Update the pointer, data can move during a reallocation */
	      *func_list = f_list;
	    }

	  /* Add the function in the table */
	  f_list[cnum] = name;

	  *count = ++cnum;
	}
    }
  
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); 
}
Beispiel #5
0
void listline(char *var, statement *stmt, byte showline)
{
  int x;

  outcount = 0;

  if (stmt->errorflag) {
    mysprintf(var, "*ERR ");
    for (x=0; x<tokenpos; x++) mysprintf(var, " ");
    mysprintf(var, "V\n");
  }
  if (showline) mysprintf(var, "%.5d ", stmt->linenum);
  if (stmt->errorflag) {
    mysprintf(var, "%s", stmt->metalist[1].stringarg);
    return;
  }
  if (stmt->numlabels) {
    for (x=0; x<stmt->numlabels; x++)         
      mysprintf(var, "%s: ", get_labelname(stmt->labelset[x]->labelnum));
  } 
  mysprintf(var, "%s ", get_opname(stmt->opcode));
  switch(stmt->opcode) {
    case CMD_DEFFN:
      list_deffn(var, stmt);
      break;
    case CMD_REM:
      mysprintf(var, "%s", stmt->metalist[1].stringarg);
      break;
    case CMD_IF:
      list_if(var, stmt);
      break;
    case CMD_LET:
      list_let(var, stmt);
      break;
    case CMD_SETESC:
    case CMD_SETERR:
    case CMD_GOTO:
    case CMD_GOSUB:
      if (stmt->metalist[1].operation == LABELREF)
        mysprintf(var, "%s", get_labelname(stmt->metalist[1].shortarg));
      else mysprintf(var, "%.5d", stmt->metalist[1].shortarg);
      break;
    case CMD_FOR:
      list_for(var, stmt);
      break;
    case CMD_NEXT:
      mysprintf(var, "%s", get_symname(stmt->metalist[1].shortarg));
      break;
    case CMD_LIST:
    case CMD_DELETE:          
      if (stmt->metapos == 1)  
        mysprintf(var, "00001, 65534");
      else if (stmt->metapos == 2)
        mysprintf(var, "%.5d", flt2int(stmt->metalist[1].floatarg));
      else mysprintf(var, "%.5d, %.5d", flt2int(stmt->metalist[1].floatarg),
                                flt2int(stmt->metalist[3].floatarg));
      break;
    case CMD_RETURN:
    case CMD_WEND:
    case CMD_RETRY:
    case CMD_SETERRON:
    case CMD_SETERROFF:
      break;
    case CMD_ON:
      list_on(var, stmt);
      break;
    default:
      if (stmt->metapos == 1) break;
      simplifylist(var, stmt, 0, stmt->metapos);
      mysprintf(var, "%s", listpop());
      break;
  }
}
Beispiel #6
0
void simplifylist(char *var, statement *stmt, int start, int end)
{
  int y = 0, channels = 0;
  char tmp[MAX_STRING_LENGTH], *hex;
  char *tmp1, *tmp2, *tmp3;
  char *reorder[32]; int ctr = 0;

  for (y=start; y<=end; y++) {            
    oppush(0);
    if (get_sysvarname(stmt->metalist[y].operation)) {
      sprintf(tmp, "%s", get_sysvarname(stmt->metalist[y].operation));
      listpush(tmp);
    } else if (get_fncname(stmt->metalist[y].operation)) {
      if ((stmt->metalist[y].operation == OP_AND) ||
          (stmt->metalist[y].operation == OP_OR) ||
          (stmt->metalist[y].operation == OP_XOR)) goto blah;
      sprintf(tmp, "%s(", get_fncname(stmt->metalist[y].operation));
      if (stmt->metalist[y].intarg) {
        for (ctr=0; ctr<stmt->metalist[y].intarg; ctr++) {
          reorder[ctr] = SafeMalloc(MAX_STRING_LENGTH);
          reorder[ctr] = listpop();
        }
      } else {
        for (ctr=0; ctr<fnctable[get_fnc(get_fncname(stmt->metalist[y].
                operation))].numparms; ctr++) { 
          reorder[ctr] = SafeMalloc(MAX_STRING_LENGTH); 
          reorder[ctr] = listpop(); 
        }
      }     
     for (ctr=ctr-1; ctr>=0; ctr--) { 
        strcat(tmp, reorder[ctr]); 
        if (ctr) strcat(tmp, ",");
      }
      strcat(tmp, ")");
      listpush(tmp);
    } else  
blah:
      switch(stmt->metalist[y].operation) {
      case HEXSTRING:
        hex = SafeMalloc(2+(stmt->metalist[y].intarg*2));
        *hex = 0;
        sprintf(tmp, "$");
        for (ctr = 0; ctr < stmt->metalist[y].intarg; ctr++) {
          sprintf(hex, "%X", stmt->metalist[y].stringarg[ctr]);
          sprintf(hex, "%c%c", hex[strlen(hex)-2], hex[strlen(hex)-1]);
          strcat(tmp, hex);
        }
        strcat(tmp, "$");
        GC_free(hex);
        listpush(tmp);
        break;
      case 0xF5:
        if (stmt->opcode != CMD_DEFFN) listpush("<BEGINLIST>");
        break;
      case 0xF8: 
        if (stmt->opcode != CMD_DEFFN) {
          ctr = 0;
          do {
            reorder[ctr] = SafeMalloc(MAX_STRING_LENGTH);
            reorder[ctr] = listpop(); 
            if (!strcmp(reorder[ctr], "<BEGINLIST>")) break;
            ctr++; 
          } while(1);
          sprintf(tmp, "%s(", listpop());
          for (ctr = ctr-1; ctr >= 0; ctr--) {
            strcat(tmp, reorder[ctr]);
            if (ctr) strcat(tmp, ",");
          }         
          strcat(tmp, ")");
          listpush(tmp);
        }
        break;
      case 0x8DC9:
        listpush(gprog->userfunctions[stmt->metalist[y].shortarg].name);
        break;
      case 0xF1:
      case 0xEC:
        // workaround, LET handles its own commas
        if (stmt->opcode != CMD_LET) {
          sprintf(tmp, "%s,", listpop());
          listpush(tmp);
          for (ctr = 0; ctr < outcount; ctr++)
            mysprintf(var, "%s", listpop());
        }
        break;
      case 0xF4F1:
        if (channels) mysprintf(var, ") ");
        break;
      case 0xE1:
        channels = 1;
        mysprintf(var, "(%s", listpop());
        break;
      case OP_OPT:
      case OP_SEP:
      case OP_SRT:
      case OP_BNK:
      case OP_DOM:
      case OP_END:
      case OP_IND:
      case OP_IOL:
      case OP_ISZ: 
      case OP_KEY:
      case OP_SIZ:
      case OP_TBL:
      case OP_TIM:
      case OP_ERR:
      case OP_LEN:
      case OP_PWD:
      case OP_ATR:
        if (channels)
          mysprintf(var, ", %s=%s", get_symbol(stmt->metalist[y].operation), listpop());
        else {
          sprintf(tmp, "%s, %s=%s", listpop(), get_symbol(stmt->metalist[y].operation), listpop());
          listpush(tmp);
        }
        break;
      case LABELREF:
        sprintf(tmp, "%s", get_labelname(stmt->metalist[y].shortarg));
        listpush(tmp);
        break;
      case LINEREF:
        sprintf(tmp, "%.5d", stmt->metalist[y].shortarg);
        listpush(tmp);
        break;
      case MNEMONICREF:
        sprintf(tmp, "\'%s\'", stmt->metalist[y].stringarg);
        listpush(tmp);
        break;
      case 0xF7:
        tmp2 = listpop();
        sprintf(tmp, "@(%s,%s)", listpop(), tmp2);
        listpush(tmp);
        break;
      case 0xF6:
        sprintf(tmp, "@(%s)", listpop());
        listpush(tmp);
        break;
      case FLOAT:
        sprintf(tmp, "%s", flt2asc(stmt->metalist[y].floatarg));
        listpush(tmp);
        break;
      case GETVAL_STRINGARRAY:
      case SETVAL_STRINGARRAY:
      case GETVAL_STRING:
      case SETVAL_STRING:
        ctr = stmt->metalist[y].shortarg;
        tmp3 = SafeMalloc(MAX_STRING_LENGTH);
        if (stmt->metalist[y].shortarg & 0x2000) {
          ctr -= 0x2000;
          sprintf(tmp3, "(%s)", listpop());
        } else if (stmt->metalist[y].shortarg & 0x4000) {
          ctr -= 0x4000;
          tmp2 = listpop();
          sprintf(tmp3, "(%s,%s)", listpop(), tmp2);
        } else tmp3 = 0;
        if (stmt->metalist[y].shortarg & 0x8000) {
          ctr -= 0x8000;
          if (stmt->metalist[y].operation == GETVAL_STRINGARRAY ||
              stmt->metalist[y].operation == SETVAL_STRINGARRAY) {
            tmp1 = listpop(); 
            tmp2 = listpop();
            sprintf(tmp, "[%s,%s,%s]", listpop(), tmp2, tmp1);
            listpush(tmp);
          } else {
            sprintf(tmp, "[%s]", listpop());
            listpush(tmp);
          }
        } else if (stmt->metalist[y].operation == GETVAL_STRINGARRAY ||
                   stmt->metalist[y].operation == SETVAL_STRINGARRAY) {
          tmp1 = listpop();
          sprintf(tmp, "[%s,%s]", listpop(), tmp1);
          listpush(tmp);
        } else listpush(""); // noarrayref
        if (tmp3)
          sprintf(tmp, "%s%s%s", get_symname(ctr), listpop(), tmp3);
        else sprintf(tmp, "%s%s", get_symname(ctr), listpop());
        GC_free(tmp3);
        if ((stmt->metalist[y].operation == SETVAL_STRING) ||
            (stmt->metalist[y].operation == SETVAL_STRINGARRAY)) {
          if ((stmt->opcode == CMD_LET) || (stmt->opcode == CMD_FOR))
            strcat(tmp, "=");
        }
        listpush(tmp);
        break;
      case GETVAL_NUMERIC:
      case SETVAL_NUMERIC:        
      case GETVAL_NUMERICARRAY:
      case SETVAL_NUMERICARRAY:
        ctr = stmt->metalist[y].shortarg;
        if (stmt->metalist[y].shortarg & 0x8000) {
          ctr -= 0x8000;
          if (stmt->metalist[y].operation == GETVAL_NUMERICARRAY ||
              stmt->metalist[y].operation == SETVAL_NUMERICARRAY) {
            tmp1 = listpop(); 
            tmp2 = listpop();
            sprintf(tmp, "[%s,%s,%s]", listpop(), tmp2, tmp1);
            listpush(tmp);
          } else {
            sprintf(tmp, "[%s]", listpop());
            listpush(tmp);
          }
        } else if (stmt->metalist[y].operation == GETVAL_NUMERICARRAY ||
                   stmt->metalist[y].operation == SETVAL_NUMERICARRAY) {
          tmp1 = listpop();
          sprintf(tmp, "[%s,%s]", listpop(), tmp1);
          listpush(tmp);
        } else listpush(""); // noarrayref
        sprintf(tmp, "%s%s", get_symname(ctr), listpop());
        if (stmt->metalist[y].operation == SETVAL_NUMERIC ||
            stmt->metalist[y].operation == SETVAL_NUMERICARRAY) 
         if ((stmt->opcode == CMD_LET) || (stmt->opcode == CMD_FOR))
           strcat(tmp, "=");
        listpush(tmp);
        break;
      case SHORTLITERAL:
        sprintf(tmp, "\"%s\"", stmt->metalist[y].stringarg);
        listpush(tmp);
        break;
      case OP_NEGATE:
        sprintf(tmp, "(-%s)", listpop());
        listpush(tmp);
        break;
      case OP_STRCAT:
        tmp2 = listpop(); 
        sprintf(tmp, "%s+%s", listpop(), tmp2);
        listpush(tmp); 
        break;
      case OP_AND:
      case OP_XOR:
      case OP_OR:
      case OP_LESSTHAN:
      case OP_GREATTHAN:
      case OP_NOTEQUAL:
      case OP_EQUALSCMP:
      case OP_LTEQ:
      case OP_GTEQ:
      case OP_ADD:
      case OP_SUBTRACT:
      case OP_MULTIPLY:
      case OP_DIVIDE:
      case OP_EXPONENT:
        oppop();
        if (oppop() >= getprec(get_symbol(stmt->metalist[y].operation))) {
          tmp3 = listpop();
          tmp1 = SafeMalloc(strlen(tmp3)+2);
          sprintf(tmp1, "(%s)", tmp3);
        } else tmp1 = listpop();
        if (oppop() >= getprec(get_symbol(stmt->metalist[y].operation))) {
          tmp3 = listpop();
          tmp2 = SafeMalloc(strlen(tmp3)+2);
          sprintf(tmp2, "(%s)", tmp3);
        } else tmp2 = listpop();
        oppush(getprec(get_symbol(stmt->metalist[y].operation)));
        sprintf(tmp, "%s%s%s", tmp2, get_symbol(stmt->metalist[y].operation), tmp1);
        listpush(tmp);
        break;
    }
  }
}
Beispiel #7
0
/** 
 * Print the chosen symbol table 
 * @param file
 * @param sect
 * @param tab
 * @param num
 * @param regx
 * @param get_symname
 * @return
 */
int		ds(elfshobj_t	*file,
		   elfshsect_t	*sect,
		   u_int        num,
		   regex_t	*regx,
		   char		*(*get_symname)(elfshobj_t *f, elfsh_Sym *s))
{
  elfsh_Sym	*table;
  char		*name;
  char		*type;
  char		*bind;
  u_int		typenum;
  u_int		bindnum;
  u_int		foff;
  u_int		index;
  char		*sect_name;
  char		buff[512];
  char		off[50];
  char		type_unk[ERESI_MEANING + 1];
  char		bind_unk[ERESI_MEANING + 1];

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Sort the table if necessary */
  if (world.state.sort != NULL)
    switch (*world.state.sort)
      {
      case ELFSH_SORT_BY_ADDR:
	table = sect->altdata;
	break;
      case ELFSH_SORT_BY_SIZE:
	table = sect->terdata;
	break;
      default:
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
			  "Unknown sort mode", -1);
      }

  /* Avoid reading inexistant memory in the process for .symtab */
  else
    table = (elfsh_Sym *) (sect->shdr->sh_addr ? elfsh_readmem(sect) : sect->data);

  /* Browse symtab */
  for (index = 0; index < num; index++)
    {

      /* Retreive names */
      typenum = elfsh_get_symbol_type(table + index);
      bindnum = elfsh_get_symbol_bind(table + index);
      type = (char *) (typenum > ELFSH_SYMTYPE_MAX ? 
		       revm_build_unknown(type_unk, "type", typenum) : 
		       elfsh_sym_type[typenum].desc);
      bind = (char *) (bindnum >= ELFSH_SYMBIND_MAX ?
		       revm_build_unknown(bind_unk, "type", bindnum) : 
		       elfsh_sym_bind[bindnum].desc);
      name = get_symname(world.curjob->curfile, table + index);
      sect_name = NULL;
      sect = elfsh_get_parent_section(world.curjob->curfile, 
				      table[index].st_value, 
				      NULL);
      if (sect == NULL && table[index].st_shndx)
	sect = elfsh_get_section_by_index(world.curjob->curfile, 
					  table[index].st_shndx,
					  NULL, NULL);
      if (sect != NULL)
	sect_name = elfsh_get_section_name(world.curjob->curfile, sect);

      /* Fixup names */
      if (name == NULL || *name == 0)
	name = ELFSH_NULL_STRING;
      if (type == NULL || *type == 0)
	type = ELFSH_NULL_STRING;
      if (bind == NULL || *bind == 0)
	bind = ELFSH_NULL_STRING;
      if (sect_name == NULL)
	sect_name = ELFSH_NULL_STRING;
      foff = (!table[index].st_value ? 0 : 
	      elfsh_get_foffset_from_vaddr(world.curjob->curfile, 
					   table[index].st_value));
					
      if (sect && sect->shdr->sh_addr != table[index].st_value)
	snprintf(off, sizeof(off), " + %s", 
		 revm_colornumber("%u", (u_int) (table[index].st_value - sect->shdr->sh_addr)));
      else
	*off = '\0';



      /* Different output depending on the quiet flag */
      if (!world.state.revm_quiet)
	{
	  snprintf(buff, sizeof(buff), 
		   " %s %s %s %s %s%s "
		   "%s%s %s%s %s%s => %s%s\n",
		   revm_colornumber("[%03u]", index), 
		   revm_coloraddress(XFMT, (eresi_Addr) elfsh_get_symbol_value(table + index) + file->rhdr.base), 
		   revm_colortypestr_fmt("%-8s", type), 
		   revm_colorstr_fmt("%-40s", name),
		   revm_colorfieldstr("size:"),
		   revm_colornumber("%010u", elfsh_get_symbol_size(table + index)), 				  
		   revm_colorfieldstr("foffset:"),
		   revm_colornumber("%06u", foff),
		   revm_colorfieldstr("scope:"),
		   revm_colortypestr_fmt("%-6s", bind), 
		   revm_colorfieldstr("sctndx:"),
		   revm_colornumber("%02u", elfsh_get_symbol_link(table + index)),
		   revm_colorstr(sect_name), off);
	}

      else
	{
	  snprintf(buff, sizeof(buff), 
		   " %s %s %s %s %s%s %s%s %s%-6s\n",
		   revm_colornumber("[%03u]", index), 
		   revm_coloraddress(XFMT, (eresi_Addr) elfsh_get_symbol_value(table + index) + file->rhdr.base),
		   revm_colortypestr_fmt("%-8s", type), revm_colorstr_fmt("%-15s", name), 
		   revm_colorfieldstr("sz:"),
		   revm_colornumber("%06u", elfsh_get_symbol_size(table + index)),
		   revm_colorfieldstr("foff:"),
		   revm_colornumber("%06u", foff),
		   revm_colorfieldstr("scop:"),
		   revm_colortypestr_fmt("%-6s", bind));
	}
      
      if (regx == NULL || 
	  (regx != NULL && regexec(regx, buff, 0, 0, 0) == 0))
	{
	  /* If the user ask quit, we just break */
	  if (revm_output(buff) == -1)
	    break;
	}

      revm_endline();
    }

  revm_endline();
  revm_output("\n");
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Beispiel #8
0
// main entry into parser
void encode_rpn()
{
  statement *stmt, *tempstmt = gprog->firststmt;
  struct labelset *label;
  unsigned int x = 0, y = 0;
  int channum = 0, lastfnc = 0, lastvar = 0, ifcount = 0;
  byte display = 0, watchchannel = 0, special = 0; 
  char *cont;
  symbol *sym;

begin:

  stmt = SafeMalloc(sizeof(statement));
  stmtinit(stmt);

  for (x=0; x<MAX_STMT_METAS; x++) {
    stmt->metalist[x].operation = 0;
    stmt->metalist[x].floatarg.mantisa.i = 0;
    stmt->metalist[x].floatarg.exp = 0;
    stmt->metalist[x].shortarg = 0;
    for (y=0; y<MAX_STRING_LENGTH; y++)
      stmt->metalist[x].stringarg[y] = 0;
  }

  special = 0;
  foundequals = 0;
  firstvar = 1;
  numlabels = 0;
  envinfo.stmttype = 0;
  tokenpos = 0;
  token_type = 1;
  lastopcode = 0;

  for (x=0; x<32; x++) { numargs[x] = 0; parenstack[x] = 0; }

  do {
     get_token();
     tokenpos += strlen(token);
     if(!checkoption(get_cmdindex(get_opname(stmt->opcode)), token, token_type))
       lineerror(stmt, __FILE__, __LINE__);
     // hack to avoid using runtime system
     // using runtime system would change the last executed line info.
//     if ((!strcmp(token, "PBSTEP")) && (token_type == TOK_COMMAND)) 
//       dbg_step();

     switch (token_type) {
       case TOK_ERROR:
         lineerror(stmt, __FILE__, __LINE__);
         break;

       case TOK_COMMAND:
         lastopcode = get_opcode(token);
         if (cmdtable[get_cmdindex(token)].options & IO_CHANNEL)
           watchchannel = 1;
         else watchchannel = 0;
         stmt->opcode = get_opcode(token);
         if (stmt->opcode == CMD_LET) goto loop2;
         else goto loop;

       case TOK_NUMBER:
         stmt->opcode = 0;
         stmt->linenum = atoi(token);
         break;

       default:
         buffermeta(stmt, token_type, token);
         goto loop2; 
     }

     buffermeta(stmt, token_type, token);

loop:
     get_token();
     if (checkerr == 2) checkerr = 1;
     else if (checkerr == 1) {
       if (token[0] == '=') {
         if (stmt->metalist[stmt->metapos-2].operation == 0xEC)
           stmt->metapos-=2;
         else stmt->metapos--;
         push("ERR", TOK_OPERATOR);
       } else if (token[0] == '(') {
         prog--;
         stmt->metapos--;
         strcpy(token, "ERR");
         token_type = TOK_FUNCTION;
       } 
       checkerr = 0;
     }
     if (lastopcode == CMD_SETERR) {
       if (!strcmp(token, "ON")) lastopcode = CMD_SETERRON;
       if (!strcmp(token, "OFF")) lastopcode = CMD_SETERROFF;
     }
     if (!strcmp(token, "RECORD")) {
       if (stmt->opcode == CMD_READ) lastopcode = CMD_READRECORD;
       if (stmt->opcode == CMD_WRITE) lastopcode = CMD_WRITERECORD;
       if (stmt->opcode == CMD_EXTRACT) lastopcode = CMD_EXTRACTRECORD;
       if (stmt->opcode == CMD_FIND) lastopcode = CMD_FINDRECORD;
       if (stmt->opcode == CMD_PRINT) lastopcode = CMD_PRINTRECORD;
       token_type = lasttype;
       goto loop;
     }
     if (lastopcode == CMD_REM) {
       stmt->metalist[1].operation = 0xF5;
       tokenpos -= 2;
       if (input[tokenpos] == '\"') x = tokenpos; else x = tokenpos+2;
       stmt->metalist[1].shortarg = strlen(input) - x;
       y = 0;
       for (x=x; x<strlen(input); x++)
       { stmt->metalist[1].stringarg[y] = input[x]; y++; }
       stmt->metalist[1].stringarg[y] = '\0';
       stmt->metapos++;
       if (stmt->linenum) insertstmt(gprog, stmt);
       return; 
     }
     tokenpos += strlen(token);
     if(!checkoption(get_cmdindex(get_opname(lastopcode)), token, token_type))
       lineerror(stmt, __FILE__, __LINE__);

loop2:
     switch (token_type) {
       case TOK_SEMICOLON:
         popstack(stmt, -1);
         if (!stmt->linenum) { execline(gprog, stmt); stmtinit(stmt); }
         break;

       case TOK_COLON:
         if ((stmt->metalist[stmt->metapos-1].operation == SETVAL_NUMERIC) ||
             (stmt->metalist[stmt->metapos-1].operation == GETVAL_NUMERIC) ||
             (stmt->metalist[stmt->metapos-1].operation == LABELREF)) {
           label = SafeMalloc(sizeof(struct labelset));
           sym = idx2sym(gprog, stmt->metalist[stmt->metapos-1].shortarg); 
           label->labelnum = addlabel(gprog, sym->name, stmt->linenum);
           for (x=0; x<MAX_STRING_LENGTH; x++)
             sym->name[x] = '\0';
           x = 0;
           stmt->metapos--;
           stmt->metalist[stmt->metapos].shortarg = 0;
           stmt->opcode = 0;
           stmt->labelset[stmt->numlabels] = label;
           stmt->numlabels++;
           firstvar = 1;
         } else {
           do {
             if (stmt->linenum == tempstmt->linenum) {
               for (x=0; x<strlen(input); x++) 
                 if (input[x] == ':') break;
               y = x;
               for (x=0; x<=y; x++) input[x] = ' ';
               cont = SafeMalloc(1024*64);
               *cont = 0;
               listline(cont, tempstmt, 1);
               strcat(cont, input);
               *prog = 0; 
               prog = cont;
               display = 1;
               goto begin;
             }
             tempstmt = tempstmt->nextstmt;
           } while (tempstmt != NULL);
           numlabels++;
         }
         goto loop;

       case TOK_COMMA:
         if (parencount > 0) { 
           // comma being delimiter for system functions
           popstack(stmt, -2);
           push("(", TOK_OPERATOR);
           if (chaninfo == 1) {
             if (!channum) {
               channum = 1;
               stmt->metalist[stmt->metapos].operation = 0xE1;
               stmt->metapos++;
             }
           } else { 
             if (special == 1) numargs[parencount-1]+=10;
             else numargs[parencount-1]++; 
             envinfo.stmttype = 0; 
           }
         } else {
           // comma being delimiter for verbs
           popstack(stmt, -1); 
           buffermeta(stmt, TOK_COMMA, token); 
           for (x=0; x<32; x++) numargs[x] = 0;
           envinfo.stmttype = 0;
           foundequals = 0;
           firstvar = 1;
         }
         goto loop;

       case TOK_ERROR:
         lineerror(stmt, __FILE__, __LINE__);
         return;

       case TOK_COMMAND:
         lastopcode = get_opcode(token);
         if (cmdtable[get_cmdindex(token)].options & IO_CHANNEL)
           watchchannel = 1;
         else watchchannel = 0;
         if (!strcmp(token, "IF")) ifcount++;
         if (!stmt->opcode) {
           stmt->opcode = get_opcode(token);
           envinfo.stmttype = 0;
           goto loop;
         } else {
           popstack(stmt, -1);
           envinfo.stmttype = 0;
           if (ifcount > 0) {
             stmt->metalist[stmt->metapos].operation = 0xE7;
             stmt->metalist[stmt->metapos].shortarg = 0;
             stmt->metalist[stmt->metapos].intarg = 0;
             stmt->metapos++;
             stmt->length++;
//             watchchannel = 0;
             chaninfo = 0;
             channum = 0;
             ifcount--;
           }
           if (lastopcode == CMD_ON) {
             special = 1;
             if (!strcmp(token, "GOTO")) 
               stmt->metalist[stmt->metapos].operation = 0x00F4;
             else stmt->metalist[stmt->metapos].operation = 0x01F4;
             stmt->length += 2;
             stmt->metapos++;
           } else
             buffermeta(stmt, TOK_COMMAND, token);
           goto loop;
         }
       break;
       
       case TOK_RESERVED:
         popstack(stmt, -1);
         envinfo.stmttype = 0;
         lineref = 0;
         if (!strcmp(token, "ELSE")) {
           stmt->metalist[stmt->metapos].operation = 0xE7;
           stmt->metalist[stmt->metapos].intarg = 0;
           stmt->metalist[stmt->metapos].shortarg = 0;
           stmt->metapos++;
           stmt->metalist[stmt->metapos].operation = 0xE2;
           stmt->metalist[stmt->metapos].intarg = 0;
           stmt->metalist[stmt->metapos].shortarg = 0;
           stmt->metapos++; 
           stmt->length+=2;
           envinfo.stmttype = 0;
           chaninfo = 0;
           channum = 0;
         }
         goto loop;

       case TOK_DONE:
         if ((stmt->linenum) && (!stmt->opcode)) deletestmt(gprog,stmt->linenum);
         else {
           popstack(stmt, -1);
           if (stmt->opcode == CMD_LET && foundequals == 0) lineerror(stmt, __FILE__, __LINE__);
           if (parencount > 0 || numlabels < 0) lineerror(stmt, __FILE__, __LINE__);
           if (stmt->linenum) { if (!stmt->errorflag) insertstmt(gprog, stmt); }
           else if (stmt->opcode) { if (!stmt->errorflag) 
                  { execline(gprog, stmt); } }
         }
         if (display) {
           GC_realloc(cont, strlen(cont));
           listprog(gprog, stmt->linenum, stmt->linenum);
         }
         return;

       case TOK_USERFUNCTION:
         if (lastopcode == CMD_DEFFN)
           addfunction(gprog, token, stmt->linenum, 1);
         else addfunction(gprog, token, stmt->linenum, 0);
         if (token[strlen(token)-1] == '$') parenstack[parencount] = 8;
           else parenstack[parencount] = 7;
         buffermeta(stmt, TOK_USERFUNCTION, token);
         break;

       case TOK_FUNCTION:
         lastfnc = get_fnc(token);
         numlabels++;
       case TOK_OPERATOR: 
         if (token[0] == '[') {
           special = 1;
           cont = get_symname(lastvar);
           if (cont[strlen(cont)-1] == '$') 
             parenstack[parencount] = 2;
           else parenstack[parencount] = 1;
           numlabels++;
           goto openparen;
         } else if (token[0] == ']') {  
           numargs[parencount-1] += 9;
           popstack(stmt, -2);
           envinfo.stmttype = parenstack[parencount];
           token_type = TOK_ARRAY;
           special = 0;
           goto loop;
         } else if (token[0] == '-') {
           // placeholder
           if ((lasttype == TOK_OPERATOR) || (lasttype == TOK_RESERVED))
             token[0] = '_';
           evalstack(stmt);
           goto loop;
         } else if (token[0] == '(') {
openparen:
           if (lasttype == TOK_COMMAND) {
             if (watchchannel == 1)
               chaninfo = 1;
           } else if (lasttype == TOK_ARRAY) {
             envinfo.stmttype = 0;
             numargs[parencount]++;
             push(token, token_type);
             goto loop;
           } else if (lasttype == TOK_SETVAL) { 
             push(get_symname(lastvar), TOK_SETVAL);
             stmt->metapos--;
             stmt->metalist[stmt->metapos].shortarg = 0; 
             numlabels++;
             cont = get_symname(lastvar);
             if (cont[strlen(cont)-1] == '$') 
               parenstack[parencount] = 2;
             else parenstack[parencount] = 1;
           } else if (lasttype == TOK_VARIABLE) {
             push(get_symname(lastvar), TOK_VARIABLE);
             numlabels++;
             stmt->metapos--;
             stmt->metalist[stmt->metapos].shortarg = 0; 
             cont = get_symname(lastvar);
             if (cont[strlen(cont)-1] == '$') 
               parenstack[parencount] = 2;
             else parenstack[parencount] = 1;
           } else if (lasttype == TOK_USERFUNCTION) {
             stmt->metapos--;
             stmt->metalist[stmt->metapos].operation = 0xF5;
             stmt->metapos++;
             stmt->length++;
           } else if (lasttype == TOK_FUNCTION) {
             if ((envinfo.stmttype != fnctable[lastfnc].returntype) &&
                 (envinfo.stmttype != 0))
               lineerror(stmt, __FILE__, __LINE__);
             else parenstack[parencount] = fnctable[lastfnc].returntype;
           } else parenstack[parencount] = 1;
           envinfo.stmttype = 0;
           numargs[parencount] = 1;
           push(token, token_type);
           goto loop;
         } else if (token[0] == ')') {
           if (parencount == 0) lineerror(stmt, __FILE__, __LINE__); 
           popstack(stmt, -2); 
           if (parenstack[parencount] == 7) {
             stmt->metalist[stmt->metapos].operation = 0xF8;
             stmt->metapos++;
             stmt->length++;
             envinfo.stmttype = 1;
           } else if (parenstack[parencount] == 8) {
             stmt->metalist[stmt->metapos].operation = 0xF8;
             stmt->metapos++;
             stmt->length++;
             envinfo.stmttype = 2;
           } else envinfo.stmttype = parenstack[parencount];
           if (lastopcode == CMD_DEFFN && foundequals == 0) {
             stmt->metapos--;
             stmt->metalist[stmt->metapos].operation = 0xF8;
             stmt->metapos++;
           }
           if (chaninfo == 1) {
             chaninfo = 0;
             if (!channum) {
               stmt->metalist[stmt->metapos].operation = 0xE1;
               stmt->metapos++;
             }
             stmt->metalist[stmt->metapos].operation = 0xF4F1;
             stmt->metapos++;
             numargs[parencount] = 0;
           }
           goto loop;
         } else { 
           evalstack(stmt); 
           goto loop; 
         }
         break;   

       case TOK_VARIABLE:
         if (get_sysvar(token)) { 
           buffermeta(stmt, TOK_SYSVAR, token); 
           numlabels++;
           goto loop;
         } else { addsymbol(gprog, token); lastvar = get_symref(token); }

       case TOK_NUMBER:
       default:
        if(!stmt->opcode) { envinfo.stmttype = 0; lastopcode = stmt->opcode = CMD_LET; }
        if ((firstvar == 1) && (token_type == TOK_VARIABLE) && 
            (lastopcode == CMD_LET || lastopcode == CMD_FOR ||
             lastopcode == CMD_FOR || lastopcode == CMD_NEXT ||
             lastopcode == CMD_DIM || lastopcode == CMD_INPUT)) {
           buffermeta(stmt, TOK_SETVAL, token);
           firstvar = 0;
           token_type = TOK_SETVAL;
        } else { numlabels++; buffermeta(stmt, token_type, token); }
        goto loop;
     }
  } while (1);
}