Print this page
11972 resync smatch


  57                "             <TR><TD>%s</TD></TR>\n"
  58                "             <TR><TD><FONT POINT-SIZE=\"21\">%s()</FONT></TD></TR>\n"
  59                "           </TABLE>>;\n"
  60                "    file=\"%s\";\n"
  61                "    fun=\"%s\";\n"
  62                "    ep=bb%p;\n",
  63                ep, sname, fname, sname, fname, ep->entry->bb);
  64 
  65         FOR_EACH_PTR(ep->bbs, bb) {
  66                 struct basic_block *child;
  67                 int ret = 0;
  68                 const char * s = ", ls=\"[";
  69 
  70                 /* Node for the bb */
  71                 printf("    bb%p [shape=ellipse,label=%d,line=%d,col=%d",
  72                        bb, bb->pos.line, bb->pos.line, bb->pos.pos);
  73 
  74 
  75                 /* List loads and stores */
  76                 FOR_EACH_PTR(bb->insns, insn) {


  77                         switch(insn->opcode) {
  78                         case OP_STORE:
  79                                 if (insn->symbol->type == PSEUDO_SYM) {
  80                                   printf("%s store(%s)", s, show_ident(insn->symbol->sym->ident));
  81                                   s = ",";
  82                                 }
  83                                 break;
  84 
  85                         case OP_LOAD:
  86                                 if (insn->symbol->type == PSEUDO_SYM) {
  87                                   printf("%s load(%s)", s, show_ident(insn->symbol->sym->ident));
  88                                   s = ",";
  89                                 }
  90                                 break;
  91 
  92                         case OP_RET:
  93                                 ret = 1;
  94                                 break;
  95 
  96                         }
  97                 } END_FOR_EACH_PTR(insn);
  98                 if (s[1] == 0)
  99                         printf("]\"");
 100                 if (ret)
 101                         printf(",op=ret");
 102                 printf("];\n");
 103 
 104                 /* Edges between bbs; lower weight for upward edges */
 105                 FOR_EACH_PTR(bb->children, child) {
 106                         printf("    bb%p -> bb%p [op=br, %s];\n", bb, child,
 107                                (bb->pos.line > child->pos.line) ? "weight=5" : "weight=10");


 113 
 114 
 115 /* Insert edges for intra- or inter-file calls, depending on the value
 116  * of internal. Bold edges are used for calls with destinations;
 117  * dashed for calls to external functions */
 118 static void graph_calls(struct entrypoint *ep, int internal)
 119 {
 120         struct basic_block *bb;
 121         struct instruction *insn;
 122 
 123         show_ident(ep->name->ident);
 124         stream_name(ep->entry->bb->pos.stream);
 125 
 126         FOR_EACH_PTR(ep->bbs, bb) {
 127                 if (!bb)
 128                         continue;
 129                 if (!bb->parents && !bb->children && !bb->insns && verbose < 2)
 130                         continue;
 131 
 132                 FOR_EACH_PTR(bb->insns, insn) {


 133                         if (insn->opcode == OP_CALL &&
 134                             internal == !(insn->func->sym->ctype.modifiers & MOD_EXTERN)) {
 135 
 136                                 /* Find the symbol for the callee's definition */
 137                                 struct symbol * sym;
 138                                 if (insn->func->type == PSEUDO_SYM) {
 139                                         for (sym = insn->func->sym->ident->symbols;
 140                                              sym; sym = sym->next_id) {
 141                                                 if (sym->namespace & NS_SYMBOL && sym->ep)
 142                                                         break;
 143                                         }
 144 
 145                                         if (sym)
 146                                                 printf("bb%p -> bb%p"
 147                                                        "[label=%d,line=%d,col=%d,op=call,style=bold,weight=30];\n",
 148                                                        bb, sym->ep->entry->bb,
 149                                                        insn->pos.line, insn->pos.line, insn->pos.pos);
 150                                         else
 151                                                 printf("bb%p -> \"%s\" "
 152                                                        "[label=%d,line=%d,col=%d,op=extern,style=dashed];\n",


 155                                 }
 156                         }
 157                 } END_FOR_EACH_PTR(insn);
 158         } END_FOR_EACH_PTR(bb);
 159 }
 160 
 161 int main(int argc, char **argv)
 162 {
 163         struct string_list *filelist = NULL;
 164         char *file;
 165         struct symbol *sym;
 166 
 167         struct symbol_list *fsyms, *all_syms=NULL;
 168 
 169         printf("digraph call_graph {\n");
 170         fsyms = sparse_initialize(argc, argv, &filelist);
 171         concat_symbol_list(fsyms, &all_syms);
 172 
 173         /* Linearize all symbols, graph internal basic block
 174          * structures and intra-file calls */
 175         FOR_EACH_PTR_NOTAG(filelist, file) {
 176 
 177                 fsyms = sparse(file);
 178                 concat_symbol_list(fsyms, &all_syms);
 179 
 180                 FOR_EACH_PTR(fsyms, sym) {
 181                         expand_symbol(sym);
 182                         linearize_symbol(sym);
 183                 } END_FOR_EACH_PTR(sym);
 184 
 185                 FOR_EACH_PTR(fsyms, sym) {
 186                         if (sym->ep) {
 187                                 graph_ep(sym->ep);
 188                                 graph_calls(sym->ep, 1);
 189                         }
 190                 } END_FOR_EACH_PTR_NOTAG(sym);
 191 
 192         } END_FOR_EACH_PTR_NOTAG(file);
 193 
 194         /* Graph inter-file calls */
 195         FOR_EACH_PTR(all_syms, sym) {
 196                 if (sym->ep)
 197                         graph_calls(sym->ep, 0);
 198         } END_FOR_EACH_PTR_NOTAG(sym);
 199 
 200         printf("}\n");
 201         return 0;
 202 }


  57                "             <TR><TD>%s</TD></TR>\n"
  58                "             <TR><TD><FONT POINT-SIZE=\"21\">%s()</FONT></TD></TR>\n"
  59                "           </TABLE>>;\n"
  60                "    file=\"%s\";\n"
  61                "    fun=\"%s\";\n"
  62                "    ep=bb%p;\n",
  63                ep, sname, fname, sname, fname, ep->entry->bb);
  64 
  65         FOR_EACH_PTR(ep->bbs, bb) {
  66                 struct basic_block *child;
  67                 int ret = 0;
  68                 const char * s = ", ls=\"[";
  69 
  70                 /* Node for the bb */
  71                 printf("    bb%p [shape=ellipse,label=%d,line=%d,col=%d",
  72                        bb, bb->pos.line, bb->pos.line, bb->pos.pos);
  73 
  74 
  75                 /* List loads and stores */
  76                 FOR_EACH_PTR(bb->insns, insn) {
  77                         if (!insn->bb)
  78                                 continue;
  79                         switch(insn->opcode) {
  80                         case OP_STORE:
  81                                 if (insn->src->type == PSEUDO_SYM) {
  82                                   printf("%s store(%s)", s, show_ident(insn->src->sym->ident));
  83                                   s = ",";
  84                                 }
  85                                 break;
  86 
  87                         case OP_LOAD:
  88                                 if (insn->src->type == PSEUDO_SYM) {
  89                                   printf("%s load(%s)", s, show_ident(insn->src->sym->ident));
  90                                   s = ",";
  91                                 }
  92                                 break;
  93 
  94                         case OP_RET:
  95                                 ret = 1;
  96                                 break;
  97 
  98                         }
  99                 } END_FOR_EACH_PTR(insn);
 100                 if (s[1] == 0)
 101                         printf("]\"");
 102                 if (ret)
 103                         printf(",op=ret");
 104                 printf("];\n");
 105 
 106                 /* Edges between bbs; lower weight for upward edges */
 107                 FOR_EACH_PTR(bb->children, child) {
 108                         printf("    bb%p -> bb%p [op=br, %s];\n", bb, child,
 109                                (bb->pos.line > child->pos.line) ? "weight=5" : "weight=10");


 115 
 116 
 117 /* Insert edges for intra- or inter-file calls, depending on the value
 118  * of internal. Bold edges are used for calls with destinations;
 119  * dashed for calls to external functions */
 120 static void graph_calls(struct entrypoint *ep, int internal)
 121 {
 122         struct basic_block *bb;
 123         struct instruction *insn;
 124 
 125         show_ident(ep->name->ident);
 126         stream_name(ep->entry->bb->pos.stream);
 127 
 128         FOR_EACH_PTR(ep->bbs, bb) {
 129                 if (!bb)
 130                         continue;
 131                 if (!bb->parents && !bb->children && !bb->insns && verbose < 2)
 132                         continue;
 133 
 134                 FOR_EACH_PTR(bb->insns, insn) {
 135                         if (!insn->bb)
 136                                 continue;
 137                         if (insn->opcode == OP_CALL &&
 138                             internal == !(insn->func->sym->ctype.modifiers & MOD_EXTERN)) {
 139 
 140                                 /* Find the symbol for the callee's definition */
 141                                 struct symbol * sym;
 142                                 if (insn->func->type == PSEUDO_SYM) {
 143                                         for (sym = insn->func->sym->ident->symbols;
 144                                              sym; sym = sym->next_id) {
 145                                                 if (sym->namespace & NS_SYMBOL && sym->ep)
 146                                                         break;
 147                                         }
 148 
 149                                         if (sym)
 150                                                 printf("bb%p -> bb%p"
 151                                                        "[label=%d,line=%d,col=%d,op=call,style=bold,weight=30];\n",
 152                                                        bb, sym->ep->entry->bb,
 153                                                        insn->pos.line, insn->pos.line, insn->pos.pos);
 154                                         else
 155                                                 printf("bb%p -> \"%s\" "
 156                                                        "[label=%d,line=%d,col=%d,op=extern,style=dashed];\n",


 159                                 }
 160                         }
 161                 } END_FOR_EACH_PTR(insn);
 162         } END_FOR_EACH_PTR(bb);
 163 }
 164 
 165 int main(int argc, char **argv)
 166 {
 167         struct string_list *filelist = NULL;
 168         char *file;
 169         struct symbol *sym;
 170 
 171         struct symbol_list *fsyms, *all_syms=NULL;
 172 
 173         printf("digraph call_graph {\n");
 174         fsyms = sparse_initialize(argc, argv, &filelist);
 175         concat_symbol_list(fsyms, &all_syms);
 176 
 177         /* Linearize all symbols, graph internal basic block
 178          * structures and intra-file calls */
 179         FOR_EACH_PTR(filelist, file) {
 180 
 181                 fsyms = sparse(file);
 182                 concat_symbol_list(fsyms, &all_syms);
 183 
 184                 FOR_EACH_PTR(fsyms, sym) {
 185                         expand_symbol(sym);
 186                         linearize_symbol(sym);
 187                 } END_FOR_EACH_PTR(sym);
 188 
 189                 FOR_EACH_PTR(fsyms, sym) {
 190                         if (sym->ep) {
 191                                 graph_ep(sym->ep);
 192                                 graph_calls(sym->ep, 1);
 193                         }
 194                 } END_FOR_EACH_PTR(sym);
 195 
 196         } END_FOR_EACH_PTR(file);
 197 
 198         /* Graph inter-file calls */
 199         FOR_EACH_PTR(all_syms, sym) {
 200                 if (sym->ep)
 201                         graph_calls(sym->ep, 0);
 202         } END_FOR_EACH_PTR(sym);
 203 
 204         printf("}\n");
 205         return 0;
 206 }