symcode.c 11.7 KB
/* symcode.c **************************************************

                      Anubis Web server. 
                  Dumping the symbolic code. 

***********************************************************/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "compil.h"

   
static void print_instr(FILE *fp, Expr instr)
{
  while (consp(instr))
    {
      print_expr(fp,car(instr)); 
      fprintf(fp," "); 
      instr = cdr(instr); 
    }
  if (instr != nil)
    {
      print_expr(fp,instr); 
    }
}

   
static void print_micro_context(FILE *fp, int d, Expr mctxt, Expr env)
{
  int i = 0; 
   
  while (consp(mctxt))
    {
      fprintf(fp,"\n         |       ; %3d.%-3d %-20s   ",d,i,string_content(car(car(mctxt))));
      show_type(fp,cdr(car(mctxt)),env); 
      i++;
      mctxt = cdr(mctxt);
    }
}
   
   
static U32 get_op_id_from_label(Expr label)
{
  int i; 
  for (i = 0; i < next_compiled_op; i++)
    {
      if (compiled_ops[i].addr == label)
        return compiled_ops[i].op_id; 
    }   
  //internal_error("get_op_id_from_label: op id not found for ",label); 
  return 0; 
}
   
void print_symbolic_code(FILE *fp, Expr code, U32 *offset_addr, 
        Expr init_addr_val, Expr var_del_addr_val)
{
  while (consp(code))
    {
      if (car(code) == odd_align)
        {
          if (!((*offset_addr)&1))
           fprintf(fp,"\n%8d |    odd_align",*offset_addr);
        }
      else if (car(code) == no_instr)
        {
        }
      else if (car(code) == initialization_address)
        {
           fprintf(fp,"\n%8d |    initialization_address %d",*offset_addr,integer_value(init_addr_val)); 
        }
      else if (car(code) == variables_deletion_address)
        {
    fprintf(fp,"\n%8d |    variables_deletion_address %d",*offset_addr,integer_value(var_del_addr_val)); 
        }
      else if (consp(car(code)) && car(car(code)) == jmp_neq) /* (jmp_neq <byte width> . <addr>) */ 
        {
          fprintf(fp,"\n%8d |    jmp_neq_%d %d",*offset_addr,
                                                integer_value(second(car(code))),
                                                integer_value(cdr2(car(code))));
        }
      else if (consp(car(code)) && car(car(code)) == program)
        {
          print_symbolic_code(fp,cdr(car(code)),offset_addr,init_addr_val,var_del_addr_val); 
        }
      else if (consp(car(code)) && car(car(code)) == label)
        {
          int i = integer_value(cdr(car(code)));

          if (i < 0 || i >= offsets_size)
            {
              fprintf(fp,"\n%8d |  label %d (at offset ?)",*offset_addr,i); 
            }
          else
            {
              fprintf(fp,"\n%8d |  label %d ", *offset_addr, i); 
            }
        }
      else if (consp(car(code)) && car(car(code)) == comment)
        {
          fprintf(fp,"\n         |       ; %s",string_content(cdr(car(code)))); 
        }
      else if (consp(car(code)) && car(car(code)) == address)
        {
          U32 opid = get_op_id_from_label(cdr(car(code))); 
          if (opid)
            fprintf(fp,"\n         |    address %-10d  ('%s' in '%s' at line %d)",
                    integer_value(cdr(car(code))),
                    string_content(car(operations[opid].names)),
                    string_content(operations[opid].file_name),
                    integer_value(operations[opid].line));
          else
            fprintf(fp,"\n         |    address %-10d",
                    integer_value(cdr(car(code)))); 
        }
      else if (consp(car(code)) && car(car(code)) == type_list)
        {
          Expr types = cdr(car(code)); 
          fprintf(fp,"\n         |       ;    for types:");
          fprintf(fp,"\n         |       ; ");
          while (consp(types))
            {
              fprintf(fp,"\n         |       ; ");
              show_type(fp,car(types),nil); 
              types = cdr(types);
            }
          fprintf(fp,"\n         |       ; ");
        }
      else if (consp(car(code)) && car(car(code)) == header)
        {
          fprintf(fp,"\n---------|--------------------------------------------------------"
                  "\n         |"
                  "\n         |         %s"
                  "\n         |",string_content(cdr(car(code)))); 
        }
      else if (consp(car(code)) && car(car(code)) == load_int32)
        {
          fprintf(fp,"\n%8d |    load_int32 %d",*offset_addr,cdr(car(code))); 
        }
      else if (consp(car(code)) && car(car(code)) == code_for)
        {
          fprintf(fp,"\n         |       ; code for "); 
          print_expr(fp,second(car(code))); 
        }
      else if (consp(car(code)) && car(car(code)) == string)
        {
          fprintf(fp,"\n%8d |    ",*offset_addr); 
          print_instr(fp,car(code)); 
          fprintf(fp,"                         (\"%s\")",
                  string_content(compiled_strings[integer_value(cdr(car(code)))].string)); 
        }
      else if (consp(car(code)) && car(car(code)) == context)
        {
          Expr ctxt = second(car(code));
          Expr env = cdr2(car(code));  
          int d = 0; 
   
          //debug(ctxt); 
   
          fprintf(fp,"\n         |       ;--- stack ------------------------"); 
          while(consp(ctxt))
            {
              if (is_string(car(car(ctxt))))
                {
                  fprintf(fp,"\n         |       ; %3d     %-20s   ",d,string_content(car(car(ctxt)))); 
                  show_type(fp,cdr(car(ctxt)),env); 
                }
              else if (car(car(ctxt)) == ret)
                {
                  fprintf(fp,"\n         |       ; %3d                            (return address)",
                          d); 
                }
              else if (car(car(ctxt)) == f_micro_ctxt)
                {
                  /*
                  fprintf(fp,"\n         |       ; %3d     ---- micro context ----",
                          d); 
                  */
                  if (second(car(ctxt)) != nil)
                    {
                      fprintf(fp,"\n         |       ; %3d     %-20s   ",
                              d,string_content(second(car(ctxt))));
                      show_type(fp,third(car(ctxt)),env); 
                    }
                  print_micro_context(fp,d,cdr3(car(ctxt)),env);
                }
              else
                {
                  fprintf(fp,"\n         |       ; %3d                            ",d); 
                  show_type(fp,cdr(car(ctxt)),env); 
                }
              ctxt = cdr(ctxt); 
              d++; 
            }	 
          fprintf(fp,"\n         |       ;----------------------------------");
        }
      else
        {
          fprintf(fp,"\n%8d |    ",*offset_addr); 
          print_instr(fp,car(code)); 
        }
      if (!(consp(car(code)) && car(car(code)) == program))
        *offset_addr += instruction_size(car(code),*offset_addr);
      code = cdr(code); 
    }
  //fprintf(fp,"\n\n"); 
}



#ifdef toto   
void dump_symbolic_code(Expr init_addr_val)
{
  FILE * symcode_txt = fopenz("symcode.txt","wt"); 
  int i, j; 
  U32 offa; 

  fprintf(symcode_txt,
          "***** Zero parameter operation schemes ******\n\n\n"); 
  for (i = 0; i < next_operation; i++)
    if (operations[i].parms == nil)
      {
        int op_i_id = get_op_instance_id(
                        new_integer(
                          ((get_file_id(string_content(operations[i].file_name)))<<23) | 
                          ((integer_value(operations[i].line))<<8)),
			i,nil,nil);
	Expr addr = compiled_ops[op_i_id].addr;
	if (integer_value(operations[i].line) == 0)
	  fprintf(symcode_txt,"Code for operation '%s' (predefined) is at address %d.\n",
		  string_content(car(operations[i].names)),
		  integer_value(addr)); 
	else
	  fprintf(symcode_txt,"Code for operation '%s' (%s, line %d) is at address %d.\n",
		  string_content(car(operations[i].names)),
		  string_content(operations[i].file_name),
		  integer_value(operations[i].line),
		  integer_value(addr)); 
      }

  fprintf(symcode_txt,
          "\n\n\n\n***** Definitions of types ******\n\n\n"); 
  for (i = 0; i < next_type; i++)
    {
      fprintf(symcode_txt,"\n\n[%3d] Definition of type:   '%s'",i,string_content(types[i].name)); 
      fprintf(symcode_txt,"\n   Parameters: ");
      print_expr(symcode_txt,types[i].parms); 
      fprintf(symcode_txt,"\n   Definition: ");
      print_expr(symcode_txt,types[i].def); 
      fprintf(symcode_txt,"\n   References: ");
      print_expr(symcode_txt,types[i].typerefs);    
    }

  fprintf(symcode_txt,
          "\n\n\n\n***** Implementations of types ******\n\n\n"); 
  for (i = 0; i < next_implem; i++)
    {
      fprintf(symcode_txt,"\n[%3d] Type: ",i); 
      show_type(symcode_txt,implems[i].type,implems[i].env); 
      fprintf(symcode_txt,"\n   implementation: "); 
      print_expr(symcode_txt,implems[i].implem); 
    }

  fprintf(symcode_txt,
          "\n\n\n\n***** Symbolic code of instances *****\n\n\n"); 
  for (i = 0; i < next_compiled_op; i++)
    {
      if (integer_value(operations[compiled_ops[i].op_id].line) == 0)
	fprintf(symcode_txt,";--- Instance of '%s' (predefined), with parameters ",
		string_content(car(operations[compiled_ops[i].op_id].names))); 
      else
	fprintf(symcode_txt,";--- Instance of '%s' (%s, line %d), with parameters ",
		string_content(car(operations[compiled_ops[i].op_id].names)),
		string_content(operations[compiled_ops[i].op_id].file_name),
		integer_value(operations[compiled_ops[i].op_id].line)); 
      print_expr(symcode_txt,operations[compiled_ops[i].op_id].parms); 
      fprintf(symcode_txt," = "); 
      show_types(symcode_txt,compiled_ops[i].types,compiled_ops[i].env);
      fprintf(symcode_txt," ---\n"); 

      fprintf(symcode_txt,";--- identification: "); 
	for(j = 0; j < 20; j++)
	  fprintf(symcode_txt,"%.2X",(compiled_ops[i].sha1_digest)[j]); 
      fprintf(symcode_txt," ---\n;--- made from: ");
      print_expr(symcode_txt,compiled_ops[i].characterisation); 
      fprintf(symcode_txt,"\n");  
   
      offa = 0; 
      print_symbolic_code(symcode_txt,compiled_ops[i].offline_code,&offa,init_addr_val,var_del_addr_val); 
    }

  fprintf(symcode_txt,"\n\n\n\n;***** Delete codes *****\n\n\n"); 
  for (i = 0; i < next_del_code; i++)
    {
      Expr code; 
      fprintf(symcode_txt,";--- Delete code number %d for type ",i); 
      show_type(symcode_txt,del_codes[i].type,del_codes[i].env); 
      fprintf(symcode_txt," ---\n"); 
      code = del_codes[i].offline_code; 
      offa = 0; 
      print_symbolic_code(symcode_txt,code,&offa,init_addr_val,var_del_addr_val); 
    }

  fprintf(symcode_txt,"\n\n\n\n;***** Strings *****\n\n\n"); 
  for (i = 0; i < next_compiled_string; i++)
    {
      fprintf(symcode_txt,"\n;  string %d: \"%s\"",
	      i,
	      string_content(compiled_strings[i].string)); 
    }

  fprintf(symcode_txt,"\n\n;***** Operation schemes *****\n"); 
  for (i = 0; i < next_operation; i++)
    {
      fprintf(symcode_txt,"\n\n;   names: ");
      print_expr(symcode_txt,operations[i].names); 
      fprintf(symcode_txt,"\n;   file_name: ");
      print_expr(symcode_txt,operations[i].file_name); 
      fprintf(symcode_txt,"\n;   line: ");
      print_expr(symcode_txt,operations[i].line); 
      fprintf(symcode_txt,"\n;   parms: ");
      print_expr(symcode_txt,operations[i].parms); 
      fprintf(symcode_txt,"\n;   signature: ");
      print_expr(symcode_txt,operations[i].signature); 
      fprintf(symcode_txt,"\n;   target_type: ");
      print_expr(symcode_txt,operations[i].target_type); 
      fprintf(symcode_txt,"\n;   ctxt: ");
      print_expr(symcode_txt,operations[i].ctxt); 
      fprintf(symcode_txt,"\n;   def: ");
      print_expr(symcode_txt,operations[i].def); 
      fprintf(symcode_txt,"\n;   global: %s", operations[i].global ? "yes" : "no"); 
    }
  fprintf(symcode_txt,"\n\n"); 

  fclose(symcode_txt); 
}

#endif