示例#1
0
void printrolechanges(struct heap_state *heap, struct rolemethod *rm) {
  struct genhashtable *rolechanges=rm->rolechanges;
  struct geniterator *it=gengetiterator(rolechanges);
  while(1) {
    struct rolechangesum *rcs=(struct rolechangesum *)gennext(it);
    struct rolechangeheader *rch;
    struct rolechangepath *rcp;
    if (rcs==NULL) break;
    fprintf(heap->methodfile, "%s -> %s ",rcs->origrole, rcs->newrole);
    rch=(struct rolechangeheader *)gengettable(rolechanges, rcs);
    rcp=rch->rcp;
    while(rcp!=NULL) {
      fprintf(heap->methodfile," Path: ");
      if (rcp->exact==rm->numberofcalls)
	fprintf(heap->methodfile,"Exact ");
      if (rcp->inner==2)
	fprintf(heap->methodfile,"Inner ");
      else if(rcp->inner==1)
	fprintf(heap->methodfile,"Maybe Inner ");

      printeffectregexpr(heap,rcp->expr);
      fprintf(heap->methodfile,"\n");
      rcp=rcp->next;
    }
  }
  genfreeiterator(it);
}
示例#2
0
int printtype(collection_type *collection_ptr,struct genhashtable *ght)
{
  int j=0;
  int offset=0;
  int value=0;

  struct valuepair *vp=NULL;
  if (gencontains(ght,collection_ptr->name))
    vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
  if (vp!=NULL)
    collection_ptr=(collection_type*) dwarf_entry_array[vp->index].entry_ptr;

  for(j=0;j<collection_ptr->num_members;j++) {
    dwarf_entry *entry=collection_ptr->members[j];
    if (entry->tag_name==DW_TAG_inheritance) {
      inherit * inherit_ptr=(inherit *)entry->entry_ptr;
      if (inherit_ptr->data_member_location>offset) {
	printf("   reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
	offset=inherit_ptr->data_member_location;
      }

      {
	dwarf_entry *type=inherit_ptr->target_ptr;
	collection_type *c_ptr=(collection_type*)type->entry_ptr;
	offset+=printtype(c_ptr,ght);
      }
    } else {
      member * member_ptr=(member *)entry->entry_ptr;
      char *name=member_ptr->name;
      char *newname=NULL;
      dwarf_entry *type=member_ptr->type_ptr;
      char *typestr=printname(type,GETTYPE);
      char *poststr=printname(type,POSTNAME);
      if (member_ptr->data_member_location>offset) {
	printf("   reserved byte[%ld];\n",member_ptr->data_member_location-offset);
	offset=member_ptr->data_member_location;
      }
      offset+=getsize(type);

      newname=escapestr(name);
      {
        char buf[512];
        char *dtype;
        sprintf(buf, "%s.%s\0", collection_ptr->name,newname);
        if (arrayt!=NULL&&gencontains(arrayt, &buf)) {
          genputtable(arraytype, buf, typestr);
          dtype=deref(typestr);
          printf("   %s_array * %s%s;\n",dtype,newname,poststr);
          free(dtype);
        } else
          printf("   %s %s%s;\n",typestr,newname,poststr);
      }
      free(newname);
    }
  }
  return offset;
}
示例#3
0
struct rolemethod * methodaddtable(struct heap_state * heap , struct rolemethod *method) {
  if (gencontains(heap->methodtable, method)) {
    struct rolemethod * retval=gengettable(heap->methodtable, method);
    methodfree(method);
    return retval;
  } else {
    genputtable(heap->methodtable, method,method);
    return method;
  }
}
示例#4
0
文件: dot.c 项目: fenghaitao/Harpoon
void dotrolemethod(struct genhashtable * htable, struct genhashtable *reverseroletable, struct rolemethod *rm) {
  int i;
  struct geniterator * it=gengetiterator(rm->rolechanges);
  while(1) {
    struct rolechangesum * rcs=(struct rolechangesum *) gennext(it);
    struct role* role;
    char buf[600];
    struct rolechangeheader *rch=NULL;
    if (rcs==NULL) break;
    rch=(struct rolechangeheader *)gengettable(rm->rolechanges,rcs);
    if (rch->inner) {
      role=(struct role *)gengettable(reverseroletable, rcs->origrole);
      sprintf(buf,"%s.%s\\n%s", rm->methodname->classname->classname,
	      rm->methodname->methodname, rm->methodname->signature);
      
      addtransition(htable, role->class, rcs->origrole,
		    buf ,rcs->newrole,1);
    }
  }
示例#5
0
void outputinfo(struct namer* namer, struct genhashtable *calltable, struct genhashtable *statictable) {
    FILE *classfile=fopen("fs-class","w");
    FILE *methodfile=fopen("fs-method","w");
    FILE *fieldfile=fopen("fs-field","w");
    FILE *callgraphfile=fopen("fs-callgraph","w");

    struct geniterator *it=gengetiterator(namer->classtable);
    while(1) {
	struct classname *cn=gennext(it);
	if (cn==NULL)
	    break;
	fprintf(classfile, "%s ", cn->classname);
    }
    genfreeiterator(it);

    it=gengetiterator(namer->methodtable);
    while(1) {
	struct methodname *mn=gennext(it);
	if (mn==NULL)
	    break;
	fprintf(methodfile, "%s.%s%s %d ", mn->classname->classname, mn->methodname, mn->signature, *((int *) gengettable(statictable, mn)));
    }
    genfreeiterator(it);

    it=gengetiterator(namer->fieldtable);
    while(1) {
	struct fieldname *fn=gennext(it);
	if (fn==NULL)
	    break;
	fprintf(fieldfile, "%s %s %s ", fn->classname->classname, fn->fieldname, fn->fielddesc->fielddesc);
    }
    genfreeiterator(it);

    it=gengetiterator(calltable);
    while(1) {
	struct methodname *mn=gennext(it);
	struct methodchain *mc=NULL;
	if (mn==NULL)
	    break;
	mc=gengettable(calltable, mn);
	while(mc!=NULL) {
	    fprintf(callgraphfile, "%s.%s%s ", mn->classname->classname, mn->methodname, mn->signature);	    
	    fprintf(callgraphfile, "%s.%s%s ", mc->method->classname->classname, mc->method->methodname, mc->method->signature);
	    mc=mc->caller;
	}
    }
    genfreeiterator(it);

    fclose(callgraphfile);
    fclose(classfile);
    fclose(methodfile);
    fclose(fieldfile);
}
示例#6
0
struct referencelist * calculatedominators(struct genhashtable * dommapping,struct heap_object *ho) {
  struct referencelist *rl=ho->rl;
  struct referencelist *dominators=NULL;
  while(rl!=NULL) {
    if ((*((int*)gengettable(dommapping, (rl->lv!=NULL)?((void *)rl->lv):((void *)rl->gl))))==1) {
      struct referencelist * tmpptr=(struct referencelist *)calloc(1, sizeof(struct referencelist));
      tmpptr->lv=rl->lv;
      tmpptr->gl=rl->gl;
      tmpptr->next=dominators;
      dominators=tmpptr;
    }
    rl=rl->next;
  }
  return dominators;
}
示例#7
0
// We will utilize this information to pause the target program at
// function entrances. For further information on how Fjalar
// determines the address for function entrances please see the
// "HANDLING FUNCTION ENTRY" comment below. This is called from
// mc_translate.c.
void handle_possible_entry(MCEnv* mce, Addr64 addr, IRSB* bb_orig) {
  // REMEMBER TO ALWAYS UPDATE THIS regardless of whether this is
  // truly a function entry so that handle_possible_exit() can work
  // properly:
  currentAddr = (Addr)addr;

  if(!fjalar_gcc3) {
    FunctionEntry *entry = gengettable(FunctionTable, (void *)(Addr)addr);
    if(entry) {
      find_entry_pt(bb_orig, entry);
    }
  }

  // We're not splitting entry handling based on GCC version.
  // for GCC 3.x we're going to enter at the instruction
  // corresponding to the first line of code in a function
  // (f->entryPC in Fjalar's terms)

  // For GCC 4.x we're going to use a special heuristic for
  // determining the instruction to enter at. See comment
  // "HANDLING FUNCTION ENTRY" above find_entry_pt()
  if(fjalar_gcc3) {

    /* If this is the very first instruction in the function, add a call
       to the prime_function helper. */
    handle_possible_entry_func(mce, addr, FunctionTable,
			       "prime_function",
			       &prime_function);

    /* If this is the first instruction in the function after the prolog
       (not exclusive with the condition above), add a call to the
       enter_function helper. */
    handle_possible_entry_func(mce, addr, FunctionTable_by_entryPC,
			       "enter_function",
			       &enter_function);
  } else {
    handle_possible_entry_func(mce, addr, FunctionTable_by_endOfBb,
			       "enter_function",
			       &enter_function);
  }

}
示例#8
0
void mergerolechanges(struct heap_state *heap) {
  struct geniterator *it=gengetiterator(heap->methodlist->rolechangetable);
  while(1) {
    struct rolechange *rc=(struct rolechange *)gennext(it);
    struct method *method=heap->methodlist;
    int inner=2;
    if (rc==NULL)
      break;

    while(method!=NULL) {
      struct rolemethod *rm=method->rm;
      struct genhashtable * rolechanges=rm->rolechanges;
      struct rolechangesum *rcs=(struct rolechangesum *)calloc(1,sizeof(struct rolechangesum));
      struct rolechangeheader *rch;
      struct effectregexpr *ere=NULL;
      struct rolechangepath *rcp;

      if (!(heap->options&OPTION_NORCEXPR))
	ere=buildregexpr(method->pathtable, rc->uid);

      rcs->origrole=copystr(rc->origrole);
      rcs->newrole=copystr(rc->newrole);
      if (!gencontains(rolechanges, rcs)) {
	rch=(struct rolechangeheader *)calloc(1,sizeof(struct rolechangeheader));
	if (inner)
	  rch->inner=1;
	genputtable(rolechanges,rcs,rch);
      } else {
	rch=(struct rolechangeheader *) gengettable(rolechanges,rcs);
	if (inner)
	  rch->inner=1;
	free(rcs->origrole);
	free(rcs->newrole);
	free(rcs);
      }
      /* rch points to appropriate rolechangeheader */
      /* ere points to our regular expression */
      rcp=rch->rcp;
      if (!(heap->options&OPTION_NORCEXPR)) {
      while(rcp!=NULL) {
	struct effectregexpr *ere2=rcp->expr;
	struct effectregexpr *erem=mergeeffectregexpr(ere,ere2);
	if (erem!=NULL) {
	  rcp->expr=erem;
	  if ((rcp->inner||inner)&&((inner==0)||(rcp->inner==0))) {
	    rcp->inner=1;
	  }
	  /*Update count */
	  if ((rcp->exact+1)==rm->numberofcalls)
	    rcp->exact=rm->numberofcalls;
	  if (rcp->exact<rm->numberofcalls)
	    rcp->exact=0;
	  freeeffectregexpr(ere2);
	  freeeffectregexpr(ere);
	  break;
	}
	rcp=rcp->next;
      }
      if(rcp==NULL) {
	/* Couldn't merge in */
	struct rolechangepath *rcp2=(struct rolechangepath *)calloc(1, sizeof(struct rolechangepath));
	rcp2->expr=ere;
	if(rm->numberofcalls==1)
	  rcp2->exact=1;
	rcp2->next=rch->rcp;
	rcp2->inner=inner;
	rch->rcp=rcp2;
      }
      }
      method=method->caller;
      inner=0;
    }
    free(rc->origrole);
    free(rc->newrole);
    free(rc);
  }
  genfreeiterator(it);
  genfreehashtable(heap->methodlist->rolechangetable);
  heap->methodlist->rolechangetable=NULL;
}
示例#9
0
void enter_function(FunctionEntry* f)
{
  FunctionExecutionState* newEntry;
  extern FunctionExecutionState* curFunctionExecutionStatePtr;

  ThreadId tid = VG_(get_running_tid)();
  Addr stack_ptr= VG_(get_SP)(tid);
  Addr frame_ptr = 0; /* E.g., %ebp */
  int local_stack, size;

  FJALAR_DPRINTF("[enter_function] startPC is: %x, entryPC is: %x, cu_base: %p\n",
                 (UInt)f->startPC, (UInt)f->entryPC,(void *)f->cuBase);
  FJALAR_DPRINTF("Value of edi: %lx, esi: %lx, edx: %lx, ecx: %lx\n",
      (long)VG_(get_xDI)(tid), (long)VG_(get_xSI)(tid), (long)VG_(get_xDX)(tid), (long)VG_(get_xCX)(tid));

  // Determine the frame pointer for this function using DWARF
  // location lists. This is a "virtual frame pointer" in that it is
  // used by the DWARF debugging information in providing the address
  // of formal parameters and local variables, but it may or may not
  // correspond to an actual frame pointer in the architecture. For
  // example: This will not always return %xbp on x86{-64} platforms
  // and *SHOULD*(untested) work with the -fomit-frame-pointer flag in GCC
  //
  // It usually points just above the function return address.  The
  // .debug_loc info tells how to find (calculate) the frame base
  // at any point in the program.   (markro)
  if(f->locList) {
    Addr eip = f->entryPC;
    location_list *ll;
    eip =  eip - f->cuBase;

    FJALAR_DPRINTF("\tCurrent EIP is: %x\n", (UInt)eip);
    FJALAR_DPRINTF("\tLocation list based function(offset from base: %x). offset is %lu\n",(UInt)eip, f->locListOffset);

    if (gencontains(loc_list_map, (void *)f->locListOffset)) {
      ll = gengettable(loc_list_map, (void *)f->locListOffset);

      // (comment added 2009)  
      // HACK. g++ and GCC handle location lists differently. GCC puts lists offsets
      // relative to the compilation unit, g++ uses the actual address. I'm going to
      // compare the location list ranges both to the cu_base offset, as well as
      // the function's entry point. This might break if there's every a case
      // where the compilation unit offset is a valid address in the program
      while(ll &&
            !(((ll->begin <= eip) && (ll->end >= eip)) ||
              ((ll->begin <= f->entryPC) && (ll->end >= f->entryPC)))) {
        FJALAR_DPRINTF("\tExamining loc list entry: %x - %x - %x\n", (UInt)ll->offset, (UInt)ll->begin, (UInt)ll->end);
        ll = ll->next;
      }

      if(ll) {
        FJALAR_DPRINTF("\tFound location list entry, finding location corresponding to dwarf #: %d with offset: %lld\n", ll->atom, ll->atom_offset);

        // (comment added 2013)  
        // It turns out it might not be just the contents of a register.  Some
        // 32bit x86 code does some tricky stack alignment and has to save a
        // pointer to the orginal stack frame.  This means we get passed a 
        // DW_OP_deref instead of a DW_OP_breg.  The tricky bit is we don't
        // want to go back to that address because it probably won't be equal
        // to the local frame pointer due to the stack alignment.  So the HACK
        // is to just assume the frame pointer is at EBP+8 like normal.  (markro)
        if (ll->atom == DW_OP_deref) {
            ll->atom = DW_OP_breg5;
            ll->atom_offset = 8;
        }    
        if(get_reg[ll->atom - DW_OP_breg0]) {
          frame_ptr = (*get_reg[ll->atom - DW_OP_breg0])(tid) + ll->atom_offset;
        }
      }
    }
  }


  // This is the old code to determine the frame. Fallback to it if we don't
  // have a frame_base from the location_list path. This should keep GCC 3 working
  // fine.
  if(frame_ptr == 0) {
    if (f != primed_function) {
      printf("No location list or frame pointer giving up(Mangled name: %s)\n", f->mangled_name);
      return;
    }
    primed_function = 0;

    if (f->entryPC != f->startPC) {
      /* Prolog has run, so just use the real %ebp */
      frame_ptr = VG_(get_FP)(VG_(get_running_tid)());
    } else {
      FJALAR_DPRINTF("Faking prolog\n");
      /* Don't know about prolog, so fake its effects, given we know that
         ESP hasn't yet been modified: */
      // Looks like we never get here for amd64 as -4 is clearly wrong. (10/26/2015)
      frame_ptr = stack_ptr - 4;
    }
  }

  FJALAR_DPRINTF("\tEnter function: %s - StartPC: %p, EntryPC: %p, frame_ptr: %p\n",
		 f->fjalar_name, (void *)f->startPC, (void *)f->entryPC, (void *)frame_ptr);

  newEntry  = fnStackPush(tid);
  newEntry->func = f;
  newEntry->func->FP = frame_ptr;
  newEntry->func->lowestSP = stack_ptr;
  newEntry->FP = frame_ptr;
  newEntry->lowSP = stack_ptr;
  newEntry->lowestSP = stack_ptr;
  newEntry->xAX = 0;
  newEntry->xDX = 0;
  newEntry->FPU = 0;
  newEntry->invocation_nonce = cur_nonce++;
  newEntry->func->nonce = newEntry->invocation_nonce;


  // FJALAR VIRTUAL STACK
  // Fjalar maintains a virtual stack for invocation a function. This
  // allows Fjalar to provide tools with unaltered values of formal
  // parameters at both function entry and exit, regardless of whether
  // or not the compiler chooses to use the original formal parameter
  // locations as storage for local values.

  // Initialize virtual stack and copy parts of the Valgrind stack
  // into that virtual stack
  local_stack = frame_ptr - stack_ptr + VG_STACK_REDZONE_SZB; /* in our frame */
  tl_assert(local_stack >= 0);
  FJALAR_DPRINTF("frame_ptr: %p, stack_ptr: %p, VG_STACK_REDZONE: %d\n", (void *)frame_ptr, (void *)stack_ptr, VG_STACK_REDZONE_SZB);

  // The virtual stack consists of:
  // (1) local_stack: the entirety of the function's local stack (the
  // memory between the frame pointer and the stack pointer (including the extra
  // redzone)
  // (2) The return pointer, which is sizeof(Addr) bytes
  // (3) The saved base pointer, which is sizeof(Addr) bytes
  // (4) All formal parameters passed on the stack, which is
  //     f->formalParamStackByteSize bytes

  // Let's be conservative in how much we copy over to the Virtual stack. Due to the
  // stack alignment operations in main, we may need  as much as 16 bytes over the above.
  size = local_stack + f->formalParamStackByteSize + sizeof(Addr)*2 + 32;/* plus stuff in caller's*/
  FJALAR_DPRINTF("local_stack: %p, arg_size: %x\n", (void *)(frame_ptr - f->formalParamLowerStackByteSize),
                                                    f->formalParamLowerStackByteSize);
  int delta = stack_ptr - (frame_ptr - f->formalParamLowerStackByteSize);
  if (delta < 0 )
      delta = 0;

  tl_assert(size >= 0);
  if (size != 0) {
    newEntry->virtualStack = VG_(calloc)("fjalar_main.c: enter_func",  size, sizeof(char));
    newEntry->virtualStackByteSize = size;
    newEntry->virtualStackFPOffset = local_stack;

    clear_all_tags_in_range(stack_ptr - VG_STACK_REDZONE_SZB, VG_STACK_REDZONE_SZB - delta);

    VG_(memcpy)(newEntry->virtualStack,
		(char*)stack_ptr - VG_STACK_REDZONE_SZB, size);

    // VERY IMPORTANT!!! Copy all the A & V bits over the real stack to
    // virtualStack!!!  (As a consequence, this copies over the tags
    // as well - look in mc_main.c). Note that the way do this means
    // that the copy is now guest-accessible, if they guessed the
    // VG_(calloc)ed address, which is a bit weird. It would be more
    // elegant to copy the metadata to an inaccessible place, but that
    // would be more work.
    FJALAR_DPRINTF("Copying over stack [%p] -> [%p] %d bytes\n",(void *)(stack_ptr - VG_STACK_REDZONE_SZB),  (void *)newEntry->virtualStack, size);
    mc_copy_address_range_state(stack_ptr - VG_STACK_REDZONE_SZB,
				(Addr)(newEntry->virtualStack), size);


    newEntry->func->guestStackStart = stack_ptr - VG_STACK_REDZONE_SZB;
    newEntry->func->guestStackEnd = newEntry->func->guestStackStart + size;
    newEntry->func->lowestVirtSP = (Addr)newEntry->virtualStack;

  }
  else {
    printf("Obtained a stack size of 0 for Function: %s. Aborting\n", f->fjalar_name);
    tl_assert(0);
  }


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

  if(!entry) {
      return;
  }

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

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

    entry->entryPC = addr;

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

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

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

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

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

    stmt('V',  mce, IRStmt_Dirty(di) );
  }
}
示例#11
0
void initializeTypeArray()
{
  int i;
  dwarf_entry * cur_entry;
  struct genhashtable * ght=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
  struct genhashtable * sht=NULL;

  if (rootfile!=NULL) {
    char buf[512];
    char a;
    int fd=open(rootfile,O_RDONLY);
    int offset=0;
    sht=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
    while(1) {
      if (read(fd,&a,1)>0) {
	if (a!=13&&a!=10)
	  buf[offset++]=a;
      } else
	  break;
      if (offset>0&&(a==13||a==10)) {
	buf[offset++]=0;
	{
	  char *str=copystr(buf);
	  genputtable(sht,str,str);
	}
	offset=0;
      }
    }
  }

  if (arrayfile!=NULL) {
    char buf[512];
    char sizebuf[512];
    char a;
    int fd=open(arrayfile,O_RDONLY);
    int offset=0;
    int readmore=1;
    int state=0;
    arrayt=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
    arraytype=genallocatehashtable((unsigned int (*)(void *)) & hashstring,(int (*)(void *,void *)) &equivalentstrings);
    while(readmore) {
      if (read(fd,&a,1)<=0)
        readmore=0;
      if (readmore) {
        if (a==' ') {
          state=1;
          buf[offset]=0;
          offset=0;
        } else if (a!=13&&a!=10) {
          if (state==0)
            buf[offset++]=a;
          else
            sizebuf[offset++]=a;
        }
      }
      if ((state==1)&&offset>0&&(a==13||a==10||!readmore)) {
        state=0;
	sizebuf[offset]=0;
	{
	  char *str=copystr(buf);
	  char *sizestr=copystr(sizebuf);
	  genputtable(arrayt,str,sizestr);
	}
	offset=0;
      }
    }
  }

  /* Assign names */
  for (i = 0; i < dwarf_entry_array_size; i++)
    {
      cur_entry = &dwarf_entry_array[i];
      if (entry_is_type(cur_entry))
        {
	  collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
	  int j=0;
	  int offset=0;
	  int value=0;
	  
	  for(j=0;j<collection_ptr->num_members;j++) {
	    dwarf_entry *entry=collection_ptr->members[j];
	    if (entry->tag_name==DW_TAG_inheritance) {
	      value++;
	    } else {
	      member * member_ptr=(member *)entry->entry_ptr;
	      char *name=member_ptr->name;
	      dwarf_entry *type=member_ptr->type_ptr;
	      char *typestr=printname(type,GETTYPE);
	      char *poststr=printname(type,POSTNAME);

	      if (typestr!=NULL)
		value++;
	    }
	  }
        }
    }

  for (i = 0; i < dwarf_entry_array_size; i++)
    {
      cur_entry = &dwarf_entry_array[i];
      if (entry_is_type(cur_entry))
        {
	  collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
	  int j=0;
	  int offset=0;
	  int value=0;
	  
	  for(j=0;j<collection_ptr->num_members;j++) {
	    dwarf_entry *entry=collection_ptr->members[j];
	    if (entry->tag_name==DW_TAG_inheritance) {
	      value++;
	    } else {
	      member * member_ptr=(member *)entry->entry_ptr;
	      char *name=member_ptr->name;
	      dwarf_entry *type=member_ptr->type_ptr;
	      char *typestr=printname(type,GETTYPE);
	      char *poststr=printname(type,POSTNAME);

	      if (typestr!=NULL)
		value++;
	    }
	  }

	  if (collection_ptr->name!=NULL) {
	    struct valuepair *vp=NULL;
	    if (gencontains(ght,collection_ptr->name))
	      vp=(struct valuepair *)gengettable(ght,collection_ptr->name);
	    if (vp==NULL||vp->value<value) {
	      if (vp==NULL) {
		vp=(struct valuepair*)calloc(1,sizeof(struct valuepair));
		genputtable(ght,collection_ptr->name,vp);
	      }
	      vp->value=value;
	      vp->index=i;
	    }
	  }
        }
    }

  assigntype=1;
  if (sht!=NULL) {
    int repeat=1;
    while(repeat) {
      repeat=0;
      for (i = 0; i < dwarf_entry_array_size; i++) {
	cur_entry = &dwarf_entry_array[i];
	if (entry_is_type(cur_entry)) {
	  collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);

	  int j=0;
	  int offset=0;
	  int value=0;

	  if (!gencontains(sht,collection_ptr->name))
	    continue;
	  if (gencontains(ght,collection_ptr->name)) {
	    struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
	    if (vp->index!=i)
	      continue;
	  }

	  for(j=0;j<collection_ptr->num_members;j++) {
	    dwarf_entry *entry=collection_ptr->members[j];
	    if (entry->tag_name==DW_TAG_inheritance) {
	      inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
	      dwarf_entry *typeptr=in_ptr->target_ptr;
	      collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
	      if (!gencontains(sht,sub_ptr->name)) {
		repeat=1;
		genputtable(sht,sub_ptr->name,sub_ptr->name);
	      }
	    } else {
	      member * member_ptr=(member *)entry->entry_ptr;
	      char *name=member_ptr->name;
	      dwarf_entry *type=member_ptr->type_ptr;
	      char *typestr=printname(type,GETJUSTTYPE);
	      if (typestr!=NULL&&!gencontains(sht,typestr)) {
		repeat=1;
		genputtable(sht,typestr,typestr);
	      }
	    }
	  }
	}
      }
    }
  }


  for (i = 0; i < dwarf_entry_array_size; i++)
    {
      cur_entry = &dwarf_entry_array[i];
      if (entry_is_type(cur_entry))
        {
	  collection_type* collection_ptr = (collection_type*)(cur_entry->entry_ptr);
	  int j=0;
	  int offset=0;
	  if (collection_ptr->name==NULL)
	    continue;
	  if (sht!=NULL&&!gencontains(sht,collection_ptr->name))
	    continue;
	  if (gencontains(ght,collection_ptr->name)) {
	    struct valuepair *vp=(struct valuepair*)gengettable(ght,collection_ptr->name);
	    if (vp->index!=i)
	      continue;
	  }
	  j=0;
	  printf("structure %s ",collection_ptr->name);

	  while(j<collection_ptr->num_members&&
		collection_ptr->members[j]->tag_name==DW_TAG_inheritance) {
	    inherit *in_ptr=(inherit*)collection_ptr->members[j]->entry_ptr;
	    dwarf_entry *typeptr=in_ptr->target_ptr;
	    collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
	    if (j==0)
	      printf("subclass of ");
	    else
	      printf(", ");
	    printf("%s ",sub_ptr->name);
	    j++;
	  }
	  printf("{ \n");

	  for(j=0;j<collection_ptr->num_members;j++) {
	    dwarf_entry *entry=collection_ptr->members[j];
	    if (entry->tag_name==DW_TAG_inheritance) {
	      inherit * inherit_ptr=(inherit *)entry->entry_ptr;
	      if (inherit_ptr->data_member_location>offset) {
		printf("   reserved byte[%ld];\n",inherit_ptr->data_member_location-offset);
		offset=inherit_ptr->data_member_location;
	      }
	      {
		dwarf_entry *type=inherit_ptr->target_ptr;
		collection_type *c_ptr=(collection_type*)type->entry_ptr;
		offset+=printtype(c_ptr,ght);
	      }
    	    } else {
     	      member * member_ptr=(member *)entry->entry_ptr;
	      char *name=member_ptr->name;
	      dwarf_entry *type=member_ptr->type_ptr;
	      char *typestr=printname(type,GETTYPE);
	      char *poststr=printname(type,POSTNAME);
	      char *newname=NULL;
	      if (member_ptr->data_member_location>offset) {
		printf("   reserved byte[%ld];\n",member_ptr->data_member_location-offset);
		offset=member_ptr->data_member_location;
	      }
	      offset+=getsize(type);
	      newname=escapestr(name);
              {
                char buf[512];
                char *dtype;
                sprintf(buf, "%s.%s\0", collection_ptr->name,newname);
                if (arrayt!=NULL&&gencontains(arrayt, &buf)) {
                  genputtable(arraytype, copystr(buf), typestr);
                  dtype=deref(typestr);
                  printf("   %s_array * %s%s;\n",dtype,newname,poststr);
                  free(dtype);
                } else
                  printf("   %s %s%s;\n",typestr,newname,poststr);
              }
	      free(newname);
	    }
	  }
	  if (offset<collection_ptr->byte_size)
	    printf("   reserved byte[%ld];\n",collection_ptr->byte_size-offset);
	  printf("}\n\n");
        }
    }
  if (arrayt!=NULL) {
    struct geniterator * gi=gengetiterator(arrayt);
    while(1) {
      char * str=(char *)gennext(gi);
      char *size=NULL;
      char *typestr=NULL;
      if (str==NULL)
        break;

      size=(char *)gengettable(arrayt,str);
      typestr=deref((char *)gengettable(arraytype,str));

      printf("structure %s_array {\n",typestr);
      printf("  %s elem[%s];\n",typestr,size);
      printf("}\n");
      free(typestr);
    }
    genfreeiterator(gi);
  }

}
示例#12
0
void fastscan() {
    struct methodchain *methodstack=NULL;
    struct namer *namer=allocatenamer();
    struct genhashtable *calltable=genallocatehashtable((int (*)(void *)) &hashmethod, (int (*)(void *,void *)) &comparemethod);
    struct genhashtable *statictable=genallocatehashtable((int (*)(void *)) &hashmethod, (int (*)(void *,void *)) &comparemethod);

    while(1) {
    char *line=getline();

#ifdef DEBUG
    printf("------------------------------------------------------\n");
#endif

    if (line==0) {
	outputinfo(namer, calltable,statictable);
	return;
    }
#ifdef DEBUG
    printf("[%s]\n",line);
#endif
    switch(line[0]) {
    case 'C': 
	break;
    case 'O':
	break;
    case 'N':
      {
	/* Natively created object...may not have pointer to it*/
	char buf[1000];
	sscanf(line,"NI: %s",buf);

	getclass(namer,buf);
      }
      break;
    case 'U':
      {
	/* New object*/

	char buf[1000];
	sscanf(line,"UI: %s",buf);
	getclass(namer,buf);
      }
      break;
    case 'K':
      break; 
    case 'L':
      /* Do Load */
      {
	struct localvars * lv=(struct localvars *) calloc(1, sizeof(struct localvars));
	long long uid, objuid;
	char fieldname[600], classname[600], fielddesc[600];

	sscanf(line,"LF: %s %ld %s %lld %s %s %s %lld",lv->name,&lv->linenumber, lv->sourcename, &objuid, classname, fieldname, fielddesc, &uid);
	getfield(namer,classname, fieldname,fielddesc);
	
      }
      break;
    case 'G':
      /* Do Array Load */
      break;
    case 'M':
      /* Mark Local*/
      break;
    case 'I':
      /* Enter Method*/
      {
	struct methodchain* methodchain=(struct methodchain *) calloc(1,sizeof(struct methodchain));
	char classname[600], methodname[600],signature[600];
	int isStatic;
	sscanf(line,"IM: %s %s %s %d", classname, methodname, signature, &isStatic);
	methodchain->method=getmethod(namer, classname, methodname, signature);
	methodchain->caller=methodstack;
	if (!gencontains(statictable, methodchain->method)) {
	    int * staticflag=(int *)malloc(sizeof (int));
	    *staticflag=isStatic;
	    genputtable(statictable, methodchain->method, staticflag);
	}

	if (methodstack!=NULL) {
	  if (!gencontains(calltable, methodchain->method)) {
	    struct methodchain *mc=(struct methodchain *) calloc(1,sizeof(struct methodchain));
	    mc->method=methodstack->method;
	    genputtable(calltable, methodchain->method, mc);
	  } else {
	    struct methodchain *tosearch=(struct methodchain *)gengettable(calltable, methodchain->method);
	    while(tosearch->method!=methodstack->method) {
	      if (tosearch->caller==NULL) {
		struct methodchain *mc=(struct methodchain *) calloc(1,sizeof(struct methodchain));
		mc->method=methodstack->method;
		tosearch->caller=mc;
		break;
	      }
	      tosearch=tosearch->caller;
	    }
	  }
	}
	methodstack=methodchain;
      }

      break;
    case 'R':
      /* Return from method */
      {
	struct methodchain* caller=methodstack->caller;
        free(methodstack);
        methodstack=caller;
      }
      break;
    case 'F':
      /* Field Assignment */
      {
	long long suid;
	long long duid;
	char classname[1000];
	char fieldname[1000];
	char descname[1000];
	sscanf(line,"FA: %lld %s %s %s %lld", &suid, classname, fieldname, descname, &duid);
	getfield(namer, classname, fieldname, descname);
      }
      break;
    case 'A':
      /* Array Assignment */
      {
      	long long suid;
	long long duid;
	long index;
	sscanf(line,"AA: %lld %ld %lld", &suid, &index, &duid);
      }
      break;
    }
    free(line);
  }
}