📄 slice-load.c
字号:
# include <stdio.h># include <malloc.h># include <string.h># include <fcntl.h># include "slice.h"# include "lif.h"static char sccsid[] = "@(#)slice-load.c 1.6 8/16/95";int v_opt;int c_opt = 0;/*********************************************************************** ** slice load -- routines to read K and Link files ** ***********************************************************************/int n_globals,n_procs,n_addrs,n_chains,n_heads,n_files;/*********************************************************************** ***********************************************************************/proc_ptr procs;file_ptr files;head_ptr headers;chain_ptr chains;addr_ptr addrs;id_ptr globals;/*********************************************************************** ** return true if procedure pid is a library procedure ** (a library procedure has no body definition) ** ***********************************************************************/int is_lib_proc(pid) int pid;{ return procs[pid].entry == -1;}char *var_name(pid,id) int pid,id;{ if (id <= 0) return "<no name: id is zero>"; if (pid){ if ((pid < 0) || (pid > n_procs)) return "<no name: pid out of range>"; if (id > procs[pid].n_locals) return "<no name: local id too large>"; else return procs[pid].locals[id].name; } else { if (id > n_globals) return "<no name: global id too large>"; return globals[id].name; }}set_ptr var_points_to (pid,id) int pid,id;{ int ptr_id; if (pid) ptr_id = procs[pid].locals[id].ptr_id; else ptr_id = globals[id].ptr_id; if (ptr_id) return ptr_points_to(ptr_id); return NULL;}/*********************************************************************** malloc n bytes, print fail message if not enough space ***********************************************************************/char *call_malloc(n,fail) int n; char *fail;{ char *chunk; /* static t = 0; t += n; printf ("allocate %d bytes [%d] verify(%d) (%s)\n",n,t, malloc_verify(),fail); fprintf(stdin); */ chunk = malloc(n); if (chunk) return chunk; fprintf (stderr,"Slice file load out of memory: %s\n",fail); exit(1);}get_visit_order(dir,file) char *dir; file_ptr file;{ char mess[2000]; FILE *v_file; int k,n,succ; sprintf(mess,"%s%sV",dir,file->name); v_file = fopen (mess,"r"); if (v_file){ n = 0; while (fgets(mess,2000,v_file)){ k = sscanf (mess,"%d",&succ); if (k == 1){ /* printf ("visit %2d after %2d\n",n,succ); */ if ((succ <= 0) || (succ >file->n_stmts)){ printf ("visit error at %d %d in %s\n", succ,n,file->name); } file->stmts[succ].visit_next = n; n = succ; } } fclose (v_file); }}/*********************************************************************** ** read the file dir_main/file->name (should be a C source file) ** note that the "c" in name.c is missing and must be supplied ** an index is built to allow assess by line number to the source ** ***********************************************************************/ char mess[2000],dir[2000],*at,*start;get_source (dir_main,file) char *dir_main; file_ptr file;{ char mess[2000],dir[2000],*at,*start; int fd,i; sprintf (mess,"allocating %s source",file->name); file->text = call_malloc (file->n_chars+1,mess); strcpy (dir,dir_main); at = strrchr (dir,'/'); if (at) *(at+1) = '\0'; else strcpy(dir,""); sprintf(mess,"%s%sc",dir,file->name); fd = open (mess,O_RDONLY); if (fd == -1){ printf ("could not open source: %s\n",mess); exit(1); } read (fd,file->text,file->n_chars); file->text[file->n_chars] = '\0'; close(fd); sprintf (mess,"allocating %s source index",file->name); file->src_index = (char **) call_malloc ((file->n_lines+1)* sizeof (char *),mess); at = file->text; start = at; i = 1; while (*at){ if (*at == '\n'){ file->src_index[i] = start; start = at+1; i++; } at++; } get_visit_order(dir,file);}/*********************************************************************** ** Called by read_K_file to create stmt records for a file ** ***********************************************************************/create_stmts (file) file_ptr file;{ char mess[2000]; int i; sprintf (mess,"%d stmts in %s",file->n_stmts,file->name); file->stmts = (stmt_ptr) call_malloc ((1+file->n_stmts)* sizeof(stmt_rec),mess); for (i = 1; i <= file->n_stmts; i++){ file->stmts[i].refs = file->stmts[i].defs = NULL; file->stmts[i].requires = file->stmts[i].succ = NULL; file->stmts[i].active_global = create_bit_set (n_globals + 1); file->stmts[i].active_other = NULL; file->stmts[i].joins = 0; file->stmts[i].is_return = 0; file->stmts[i].calls = NULL; file->stmts[i].visit_next = i - 1; }}/*********************************************************************** ** Read file.K -- then allocate space for objects: ** need space for: global variables, pointer chains, ** addresses, procedures, local variables, lists of ** variables declared in header files, source file recs ** ***********************************************************************/int read_k_file (name) char *name;{ char k_file_name[2000]; FILE *k_file; int i,j,ix,nx,ok; char buff[2000],mess[2000]; sprintf (k_file_name,"%sK",name); k_file = fopen (k_file_name,"r"); if (!k_file) return 1; ok = fscanf (k_file,"%*s %d %*s %d %*s %d %*s %d %*s %d %*s %d", &n_globals,&n_procs,&n_addrs,&n_chains,&n_heads,&n_files); if (ok != 6) return 1; /* printf ("globals %d procs %d addrs %d chains %d", n_globals,n_procs,n_addrs,n_chains); printf (" headers %d files %d\n",n_heads,n_files); */ chains = (chain_ptr) call_malloc ((1+n_chains)*sizeof(chain_rec), "allocating space for chains"); for (i = 1; i <= n_chains; i++){ chains[i].fields = NULL; } addrs = (addr_ptr) call_malloc ((1+n_addrs)*sizeof(addr_rec), "allocating space for addrs"); procs = (proc_ptr) call_malloc ((1+n_procs)*sizeof(proc_rec), "allocating space for procs"); for (i = 0 ; i < n_procs; i++){ fscanf (k_file,"%d",&ix); fscanf (k_file,"%d %d %d %c %s", &procs[ix].entry, &procs[ix].exit, &procs[ix].n_locals, &procs[ix].s_or_x, buff); procs[ix].global_defs = NULL; procs[ix].lib_arefs = NULL; procs[ix].other_defs = NULL; procs[ix].global_idefs = NULL; procs[ix].cdefs = NULL; procs[ix].local_idefs = NULL; procs[ix].return_stmts = NULL; procs[ix].n_formals = 0; procs[ix].returns_xpr = 0; procs[ix].calls = NULL; procs[ix].contexts = NULL; procs[ix].called_by = NULL; procs[ix].proc_name = call_malloc (strlen(buff) + 1, " space for proc name"); strcpy (procs[ix].proc_name,buff); sprintf (mess,"%d locals in %s\n",procs[ix].n_locals,buff); procs[ix].locals = (id_ptr) call_malloc ((1+procs[ix].n_locals)* sizeof(id_rec), mess); for (j = 1; j <= procs[ix].n_locals; j++){ procs[ix].locals[j].offset = 0; } } files = (file_ptr) call_malloc (n_files*sizeof(file_rec), "space for file records"); for (i = 0; i < n_files; i++){ fscanf (k_file,"%*d %d %d %d %d %s", &files[i].n_procs, &files[i].n_stmts, &files[i].n_lines, &files[i].n_chars, buff); files[i].name = call_malloc (strlen(buff) + 1, "space for file name"); strcpy (files[i].name,buff); create_stmts (&files[i]); get_source (name,&files[i]); } headers = (head_ptr) call_malloc ((n_heads)*sizeof(head_rec), "space for header file records"); for (i = 0; i < n_heads; i++){ fscanf (k_file,"%d %s",&headers[i].n,buff); nx = headers[i].n; headers[i].header_file = call_malloc (strlen(buff)+1, "space for header file name"); strcpy (headers[i].header_file,buff); headers[i].ids = (int *) call_malloc (nx*sizeof(int), "space for header file id indices"); headers[i].names = (char **) call_malloc (nx*sizeof (char *), "space for header file name pointers"); for (j = 0; j < headers[i].n; j++){ fscanf (k_file,"%d %s",&headers[i].ids[j],buff); headers[i].names[j] = call_malloc (strlen(buff)+1, "space for header file id names"); strcpy (headers[i].names[j],buff); } } globals = (id_ptr) call_malloc ((1+n_globals)*sizeof(id_rec), "space for global records"); for (i = 1; i <= n_globals; i++) globals[i].offset = 0; fclose(k_file); return 0;}/*********************************************************************** This section is obsolete **********************************************************************print_context (cx) cx_ptr cx;{ int i,pid; call_ptr call; printf ("level %d: ",cx->level); for (i = 0; i < cx->level; i++){ call = cx->branch[i]; pid = call->pid; printf ("%s ",procs[pid].proc_name); } printf ("\n");}int is_recursive (branch,level) call_ptr branch[]; int level;{ int i; for (i = 0; i < level; i++) if (branch[i]->pid == branch[level]->pid) return 1; return 0;}generate_call_contexts(){ int i; int main_pid; int level,called; cx_ptr nx,cx,new; call_ptr base,call; int n = 0; level = 1; cx = NULL; for (i = 1; i <= n_procs; i++){ if (strcmp("main",procs[i].proc_name) == 0) main_pid = i; } call = procs[main_pid].calls; while (call){ called = call->pid; if (procs[called].entry != -1){ new = (cx_ptr) call_malloc (sizeof(cx_rec),"call context"); new -> branch = (call_ptr *) call_malloc (level*sizeof(call_ptr),"call context"); new -> next_this_level = cx; cx = new; new -> level = level; new -> next_this_site = procs[called].contexts; procs[called].contexts = new; new -> branch[0] = call; print_context(new); n++; } call = call -> next; } nx = cx; while (cx){ cx = NULL; level++; while (nx){ base = nx->branch[level-2]; call = procs[base->pid].calls; if (!is_recursive(nx->branch,level-2))while (call){ called = call->pid; if (procs[called].entry != -1){ new = (cx_ptr) call_malloc (sizeof(cx_rec),"call context"); new -> branch = (call_ptr *) call_malloc (level*sizeof(call_ptr),"call context"); new -> next_this_level = cx; cx = new; new -> level = level; new -> next_this_site = procs[called].contexts; procs[called].contexts = new; for (i = 0; i < level-1; i++) new->branch[i] = nx -> branch[i]; new -> branch[level-1] = call; print_context(new); n++; } call = call -> next; } nx = nx -> next_this_level; } nx = cx; } printf ("%d calling contexts\n",n);}*//*********************************************************************** build a list of calling procs for each proc ***********************************************************************/set_called_by(){ int i; call_ptr called,by; int to_pid; for (i = 1; i <= n_procs; i++){ called = procs[i].calls; while (called){ to_pid = called->pid; by = (call_ptr) call_malloc (sizeof(call_rec), "called by records"); by -> next = procs[to_pid].called_by; procs[to_pid].called_by = by; by -> pid = i; by -> stmt = called->stmt; by -> actuals = called -> actuals; called = called -> next; } } /* for (i = 1; i <= n_procs; i++){ by = procs[i].called_by; printf ("%s called by . . .\n",procs[i].proc_name); while (by){ printf (" %s at %d\n",procs[by->pid].proc_name,by->stmt); by = by -> next; } } */}/*********************************************************************** LIF code identifies structures by a non-zero offset field ** However only a top level structure is identified in LIF code. ** mark_sub_structs finds structures declared within other structs ***********************************************************************/mark_sub_structs (vars,n_vars,id,offset) int id,offset,n_vars; id_ptr vars;{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -