Logo Search packages:      
Sourcecode: eresi version File versions  Download package

revmobj_t* parse_lookup4 ( char *  param,
char *  fmt,
u_int  sep 
)

Lookup a parameter with 4 fields, 3rd field beeing an index Used by SHT, PHT, SYMTAB, DYNSYM , Sections, .dynamic

Here need to add 1.rel[name].{L2fields} lookup

Definition at line 423 of file grammar.c.

References aspect_type_get_by_id(), ASPECT_TYPE_UNKNOW, elfsh_get_dynent_by_type(), s_L2handler::get_data, s_revm_object::get_data, s_L1handler::get_entptr, s_L2handler::get_name, s_revm_object::get_name, s_L2handler::get_obj, s_revm_object::get_obj, s_L1handler::get_obj, s_L1handler::get_obj_nam, s_revm_object::immed, s_L1handler::l2list, s_revm_object::off, s_revm_object::otype, s_revm_object::parent, parse_lookup_varlist(), revm_check_object(), revm_create_IMMED(), revm_lookup_file(), revm_lookup_index(), s_revm_object::root, s_L2handler::set_data, s_revm_object::set_data, s_L2handler::set_name, s_revm_object::set_name, s_L2handler::set_obj, s_revm_object::set_obj, s_revm_object::sizelem, strcmp(), and s_L2handler::type.

{
  revmL1_t        *l1;
  revmL2_t        *l2;
  void                  *robj;
  void                  *o1;
  int             real_index;
  int             isversion;
  u_int                 size;
  revmobj_t       *pobj;
  char                  obj[ELFSH_MEANING];
  char                  L1field[ELFSH_MEANING];
  char                  L2field[ELFSH_MEANING];
  char                  index[ELFSH_MEANING];
  char                  offfield[ELFSH_MEANING];
  char                  sizelemfield[ELFSH_MEANING];
  u_int                 off;
  u_int                 sizelem;
  int             ret;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* This handler has 3 possibles syntax */
  switch (sep)
    {
    case 4:
      ret = parse_lookup_varlist(param, fmt, obj, L1field, 
                         index, offfield, sizelemfield, L2field);
      sizelem = atoi(sizelemfield);
      off = atoi(offfield);
      break;
    case 3:
      ret = parse_lookup_varlist(param, fmt, obj, L1field, 
                         index, offfield, L2field);
      sizelem = 1;
      off = atoi(offfield);
      break;
    case 2:
      ret = parse_lookup_varlist(param, fmt, obj, L1field, index, L2field);
      sizelem = 1;
      off = 0;
      break;
    default:
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, NULL);
    }

  /* Quick test to see if we matched */
  if (ret - 2 != sep)
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, NULL);
  
  /* Let's ask the hash table for the current working file */
  robj = revm_lookup_file(obj);
  if (NULL == robj)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unknown file object",
               NULL);

  // Then, we ask the Level 1 object 
  l1 = hash_get(&L1_hash, L1field);
  if (l1 == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unknown L1 object", 
               NULL);
  else if (l1->get_entptr == NULL || l1->get_obj == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Incorrect object path",
               NULL);

  // Then the Level 2 object 
  l2 = hash_get(l1->l2list, L2field);
  if (l2 == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unknown L2 object", 
               NULL);

  // Read object 
  o1 = l1->get_obj(robj, (void *) &size);
  if (o1 == NULL)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Cannot read object", 
               NULL);
  
  pobj = revm_create_IMMED(ASPECT_TYPE_UNKNOW, 0, 0);
  pobj->immed = 0;

  // Do lookup by index or by name 
  real_index = (int) revm_lookup_index(index);
  
#if __DEBUG_LANG__
  printf("LOOKUP4 object index = %s, real_index = %u (signed = %d) \n", 
       index, real_index, real_index);
#endif

  // Index error handling 
  if (real_index < 0)
    {
      if (l1->get_obj_nam == NULL)
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
                    "Invalid L1 index", NULL);
      else
      {
        pobj->parent = l1->get_obj_nam(robj, index);
        if (pobj->parent == NULL)
          PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
                        "No L1 index by this name", NULL);
      }
    }
  
  // Get L2 object by index (or type for dynamic) 
  if (pobj->parent == NULL)
    {

      if (!strcmp(L1field, "dynamic") && !revm_isnbr(index))
      real_index = elfsh_get_dynent_by_type(robj, o1, real_index);
      
      isversion = (!strcmp(L1field, "version") ||
               !strcmp(L1field, "verdef") ||
               !strcmp(L1field, "verneed"));
      
      if (!isversion && size <= real_index)
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "L1 index too big", NULL);

      pobj->parent = l1->get_entptr(o1, real_index);

      if (isversion && pobj->parent == NULL)
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
                    "Unknown L2 object or Invalid L1 index", 
                    NULL);
    }

  // Finally we fill the intermediate object format for the guessed object 
  pobj->get_obj  = (void *) l2->get_obj;
  pobj->set_obj  = (void *) l2->set_obj;
  pobj->get_name = (void *) l2->get_name;
  pobj->set_name = (void *) l2->set_name;

  // The 2 next fields are used for 'raw' L2 of 'section' L1 
  pobj->get_data = (void *) l2->get_data;
  pobj->set_data = (void *) l2->set_data;

  pobj->otype    = aspect_type_get_by_id(l2->type);
  pobj->off      = off;
  pobj->sizelem  = sizelem;
  pobj->root     = robj;

  // Error checking 
  pobj = revm_check_object(pobj);
  if (!pobj)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
                  "Invalid REVM object", NULL);
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, pobj);
}


Generated by  Doxygen 1.6.0   Back to index