Added minimum size analysis.
[repair.git] / Repair / RepairCompiler / structextract / dumpstructures.c
index bfcc596365af9a711489a4611466d46a55cd6c09..8a95dea964b3bfc27b989b424984e415481c6a68 100755 (executable)
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #include "dumpstructures.h"
 #include "typedata.h"
 #include "elf/dwarf2.h"
-
+#include <string.h>
 
 #define GETTYPE 1
 #define POSTNAME 2
+#define GETJUSTTYPE 3
 
+int FOLLOW_PTRS=0;
+struct genhashtable * arrayt=NULL;
+struct genhashtable * arraytype=NULL;
 int process_elf_binary_data(char* filename);
 
+char *rootfile=NULL;
+char *arrayfile=NULL;
+
 int main(int argc, char **argv) {
+  int i;
   if (argc<2)
     return 0;
+  if (argc>=3)
+    rootfile=argv[2];
+  for(i=3;i<argc;i++) {
+    if (strcmp("-r",argv[i])==0)
+      FOLLOW_PTRS=1;
+    if (strcmp("-a",argv[i])==0) {
+      i++;
+      arrayfile=argv[i];
+    }
+  }
   process_elf_binary_data(argv[1]);
   daikon_preprocess_entry_array();
 }
@@ -79,7 +100,69 @@ 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;
+      }
+    }
+  }
+
   for (i = 0; i < dwarf_entry_array_size; i++)
     {
       cur_entry = &dwarf_entry_array[i];
@@ -93,15 +176,13 @@ void initializeTypeArray()
            dwarf_entry *entry=collection_ptr->members[j];
            if (entry->tag_name==DW_TAG_inheritance) {
              value++;
-             continue;
-           }
-           {
+           } 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++;
            }
@@ -123,6 +204,53 @@ void initializeTypeArray()
     }
 
   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];
@@ -133,6 +261,8 @@ void initializeTypeArray()
          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)
@@ -147,14 +277,14 @@ void initializeTypeArray()
            dwarf_entry *typeptr=in_ptr->target_ptr;
            collection_type* sub_ptr = (collection_type*)(typeptr->entry_ptr);
            if (j==0)
-             printf("subclasses ");
+             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) {
@@ -174,18 +304,53 @@ void initializeTypeArray()
              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);
-             
-             printf("   %s %s%s;\n",typestr,name,poststr);
+             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);
+  }
+
 }
 
 int printtype(collection_type *collection_ptr,struct genhashtable *ght)
@@ -193,7 +358,7 @@ 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);
@@ -217,6 +382,7 @@ int printtype(collection_type *collection_ptr,struct genhashtable *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);
@@ -225,15 +391,26 @@ int printtype(collection_type *collection_ptr,struct genhashtable *ght)
        offset=member_ptr->data_member_location;
       }
       offset+=getsize(type);
-      
-      printf("   %s %s%s;\n",typestr,name,poststr);
+
+      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;
 }
 
-
-
 int getsize(dwarf_entry *type) {
   if (type==NULL)
     return 0;
@@ -262,7 +439,7 @@ int getsize(dwarf_entry *type) {
   case DW_TAG_pointer_type: {
     return 4;
   }
-  case DW_TAG_union_type: 
+  case DW_TAG_union_type:
   case DW_TAG_structure_type: {
     collection_type *ctype=(collection_type*)type->entry_ptr;
     return ctype->byte_size;
@@ -270,7 +447,7 @@ int getsize(dwarf_entry *type) {
   case DW_TAG_subroutine_type: {
     return 4;
   }
-  case DW_TAG_typedef: 
+  case DW_TAG_typedef:
     {
       tdef * tdef_ptr=(tdef*)type->entry_ptr;
       return getsize(tdef_ptr->target_ptr);
@@ -282,9 +459,25 @@ int getsize(dwarf_entry *type) {
   }
 }
 
+char * deref(char *name) {
+  char *str=copystr(name);
+  char *initstr=str;
+  for(;(*str)!=0;str++)
+    ;
+  for(;(str!=initstr)&&((*str)!='*');str--)
+    ;
+  if ((*str)=='*') {
+    (*str)=0;
+    str--;
+    for(;(str!=initstr)&&((*str)==' ');str--)
+      (*str)=0;
+  }
+  return initstr;
+}
+
 char * printname(dwarf_entry * type,int op) {
   if (type==NULL) {
-    if (op==GETTYPE)
+    if (op==GETTYPE||op==GETJUSTTYPE)
       return NULL;
   }
 
@@ -295,7 +488,7 @@ char * printname(dwarf_entry * type,int op) {
     break;
   case DW_TAG_array_type: {
     modifier_type * modifier_ptr=(modifier_type*)type->entry_ptr;
-    if (op==GETTYPE) {
+    if (op==GETTYPE||op==GETJUSTTYPE) {
        char *typename=printname(modifier_ptr->target_ptr,op);
        return typename;
     } else if (op==POSTNAME) {
@@ -314,7 +507,7 @@ char * printname(dwarf_entry * type,int op) {
   case DW_TAG_const_type:
     {
       consttype * ctype_ptr=(consttype*)type->entry_ptr;
-      if (op==GETTYPE) {
+      if (op==GETTYPE||op==GETJUSTTYPE) {
        char *typename=printname(ctype_ptr->target_ptr,op);
        return typename;
       }
@@ -323,12 +516,22 @@ char * printname(dwarf_entry * type,int op) {
   case DW_TAG_subroutine_type: {
     return "void";
   }
-  case DW_TAG_typedef: 
+  case DW_TAG_typedef:
     {
       tdef * tdef_ptr=(tdef*)type->entry_ptr;
-      if (op==GETTYPE) {
-       char *typename=printname(tdef_ptr->target_ptr,op);
-       return typename;
+      if (op==GETTYPE||op==GETJUSTTYPE) {
+        if (tdef_ptr->target_ptr==NULL)
+          return tdef_ptr->name;
+        if (tdef_ptr->target_ptr->tag_name==DW_TAG_union_type||
+            tdef_ptr->target_ptr->tag_name==DW_TAG_structure_type) {
+          collection_type *ctype=(collection_type*)tdef_ptr->target_ptr->entry_ptr;
+          if (ctype->name!=NULL)
+            return ctype->name;
+          ctype->name=tdef_ptr->name;
+          return tdef_ptr->name;
+        }
+        char *typename=printname(tdef_ptr->target_ptr,op);
+        return typename;
       }
     }
     break;
@@ -362,6 +565,16 @@ char * printname(dwarf_entry * type,int op) {
        sprintf(newptr,"%s *",typename);
        return newptr;
       }
+    } else if (op==GETJUSTTYPE) {
+      if (!FOLLOW_PTRS)
+       return NULL;
+
+      if (modifier_ptr->target_ptr==NULL)
+       return NULL;
+      {
+       char *typename=printname(modifier_ptr->target_ptr,op);
+       return typename;
+      }
     }
   }
     break;
@@ -369,11 +582,42 @@ char * printname(dwarf_entry * type,int op) {
   case DW_TAG_structure_type: {
     collection_type *ctype=(collection_type*)type->entry_ptr;
     if (op==GETTYPE&&ctype->name==NULL&&assigntype) {
-      ctype->name=(char*)malloc(100);
-      sprintf(ctype->name,"TYPE%ld",typecount++);
+      char *newb=(char *)malloc(1000);
+      int newchars=0;
+      int i;
+      ctype->name=newb;
+      newchars=sprintf(newb,"unnamed_",type->ID);
+      newb+=newchars;
+      for(i=0;i<ctype->num_members;i++) {
+        dwarf_entry * de=ctype->members[i];
+        if (de->tag_name==DW_TAG_member) {
+          member * me=(member *)de->entry_ptr;
+          newchars=sprintf(newb,"%s",me->name);
+          newb+=newchars;
+        }
+      }
     }
     if (op==GETTYPE)
       return ctype->name;
+    if (op==GETJUSTTYPE&&ctype->name==NULL&&assigntype) {
+      char *newb=(char *)malloc(1000);
+      int newchars=0;
+      int i;
+      ctype->name=newb;
+      newchars=sprintf(newb,"unnamed_",type->ID);
+      newb+=newchars;
+      for(i=0;i<ctype->num_members;i++) {
+        dwarf_entry * de=ctype->members[i];
+        if (de->tag_name==DW_TAG_member) {
+          member * me=(member *)de->entry_ptr;
+          newchars=sprintf(newb,"%s",me->name);
+          newb+=newchars;
+        }
+      }
+    }
+    if (op==GETJUSTTYPE)
+      return ctype->name;
+
   }
     break;
   default:
@@ -389,7 +633,7 @@ char * printname(dwarf_entry * type,int op) {
   }
   if (op==POSTNAME)
     return "";
+  if (op==GETJUSTTYPE)
+    return NULL;
   return "ERROR";
 }
-
-