struct genhashtable * builddominatormappings(struct heap_state *heap, int includecurrent) { struct genhashtable * mindominator=genallocatehashtable(NULL,NULL); struct method *m=heap->methodlist; if ((includecurrent==0)&&(m!=NULL)) { struct localvars *lv=m->lv; while(lv!=NULL) { int * i=(int *)malloc(sizeof(int)); *i=0; genputtable(mindominator, lv, i); lv=lv->next; } m=m->caller; } while(m!=NULL) { struct localvars *lv=m->lv; while(lv!=NULL) { genputtable(mindominator, lv,minimaldominatorset(lv,NULL, heap, includecurrent)); lv=lv->next; } m=m->caller; } { struct globallist *globals=heap->gl; while(globals!=NULL) { genputtable(mindominator, globals,minimaldominatorset(NULL,globals,heap,includecurrent)); globals=globals->next; } } return mindominator; }
void entermethod(struct heap_state * heap, struct hashtable * ht) { //Lets show the roles!!!! /* Create maps so we can calculate roles*/ int i=0; struct genhashtable * dommap; /* Create role instantiated method structure*/ struct rolemethod * rolem=(struct rolemethod *) calloc(1, sizeof(struct rolemethod)); doincrementalreachability(heap,ht,0); dommap=builddominatormappings(heap,0); rolem->methodname=heap->methodlist->methodname; if (heap->methodlist->numobjectargs) rolem->paramroles=(char **)calloc(heap->methodlist->numobjectargs, sizeof(char *)); rolem->numobjectargs=heap->methodlist->numobjectargs; rolem->isStatic=heap->methodlist->isStatic; #ifdef DEBUG printf("Calling Context for method %s.%s%s:\n", heap->methodlist->methodname->classname->classname, heap->methodlist->methodname->methodname, heap->methodlist->methodname->signature); #endif for(;i<heap->methodlist->numobjectargs;i++) { if (heap->methodlist->params[i]!=NULL) { rolem->paramroles[i]=findrolestring(heap, dommap, heap->methodlist->params[i],0); } } methodassignhashcode(rolem); rolem=methodaddtable(heap,rolem); if (rolem->rolechanges==NULL) rolem->rolechanges=genallocatehashtable((int (*)(void *)) &rcshashcode, (int (*)(void *,void *)) &equivalentrcs); heap->methodlist->rm=rolem; /* Finished with role instantiated method.*/ /* Assign roles to all objects that might have changed*/ { struct ositerator *it=getIterator(heap->changedset); while(hasNext(it)) { struct heap_object *ho=nextobject(it); free(findrolestring(heap, dommap, ho,1)); } freeIterator(it); while(!setisempty(heap->changedset)) { struct heap_object *ho=removeobject(heap->changedset, NULL); struct fieldlist *fl=ho->fl; struct fieldlist *rfl=ho->reversefield; struct arraylist *al=ho->al; struct arraylist *ral=ho->reversearray; while(fl!=NULL) { addrolerelation(heap, fl->src, fl->fieldname, fl->object); fl=fl->next; } while(rfl!=NULL) { addrolerelation(heap, rfl->src, rfl->fieldname, rfl->object); rfl=rfl->dstnext; } while(al!=NULL) { addrolerelation(heap, al->src, getfieldc(heap->namer,al->src->class,"[]", NULL),al->object); al=al->next; } while(ral!=NULL) { addrolerelation(heap, ral->src, getfieldc(heap->namer,ral->src->class,"[]", NULL),ral->object); ral=ral->dstnext; } } } /* increment call counter */ rolem->numberofcalls++; genfreekeyhashtable(dommap); freemethodlist(heap); }
// Initialize Fjalar after command-line options are processed void fjalar_post_clo_init() { const char* DISAMBIG = ".disambig"; int DISAMBIG_LEN = VG_(strlen)(DISAMBIG); // We need to turn off some VEX IR optimizations (primarily the one which // causes separate basic blocks to be stitched together) for the purpose of // detecting entry in main. see "HANDLING FUNCTION ENTRY" in find_entry_pt() VG_(clo_vex_control).iropt_unroll_thresh = 0; VG_(clo_vex_control).guest_chase_thresh = 0; executable_filename = VG_(args_the_exename); if (fjalar_with_gdb) { int x = 0; while (!x) {} /* In GDB, say "p x=1" and then "c" to continue */ } funcs_handled= genallocatehashtable(0,(int (*)(void *,void *)) &equivalentIDs); // Handle variables set by command-line options: // Assumes that filename is first argument in client_argv FJALAR_DPRINTF("\nReading binary file \"%s\" [0x%p]\n\n", executable_filename, executable_filename); // --disambig results in the disambig filename being ${executable_filename}.disambig // (overrides --disambig-file option) if (fjalar_default_disambig) { char* disambig_filename = VG_(calloc)("fjalar_main.c: fj_po_clo_init", VG_(strlen)(executable_filename) + DISAMBIG_LEN + 1, sizeof(*disambig_filename)); VG_(strcpy)(disambig_filename, executable_filename); VG_(strcat)(disambig_filename, DISAMBIG); fjalar_disambig_filename = disambig_filename; } // There is a bug in my_libc.c that keeps printf and // putchar from intermixing properly. Using NOBUF // on stdout keeps putchar from buffering incorrectly. setNOBUF(stdout); FJALAR_DPRINTF("\n%s\n\n", fjalar_disambig_filename); // Calls into typedata.c: initialize_typedata_structures(); FJALAR_DPRINTF("Typedata structures completed\n"); // Calls into readelf.c: process_elf_binary_data(executable_filename); FJALAR_DPRINTF("Process elf binary completed\n"); // Call this BEFORE initializeAllFjalarData() so that the vars_tree // objects can be initialized for the --var-list-file option: loadAuxiliaryFileData(); // Calls into generate_fjalar_entries.c: initializeAllFjalarData(); FJALAR_DPRINTF("Fjalar data initialized\n"); if (fjalar_disambig_filename) { handleDisambigFile(); } // Call this AFTER initializeAllFjalarData() so that all of the // proper data is ready: outputAuxiliaryFilesAndExit(); FJALAR_DPRINTF("Files output\n"); // Make sure to execute this last! fjalar_tool_post_clo_init(); FJALAR_DPRINTF("Tool clo initialized\n"); }
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); } }
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); } }