symcode.c 10.5 KB
/* symcode.c **************************************************

                      Anubis Web server. 
                  Dumping the symbolic code. 

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


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

   
/* this function returns:
   
   0   if not a syscall
   1   if a syscall
   2   if a syscall32
   
   */
static int is_syscall(Expr instr)
{
  Expr name;
  if (consp(instr))
    name = car(instr); 
  else
    name = instr; 
  switch(name)
    {
#define sc_item(n,i)  case n:
   syscall_list
     return 1; 
#undef sc_item 
#define sc32_item(n,i)  case n:
   syscall32_list
     return 2;
#undef sc32_item   
    default: 
      return 0;
    }
}
   
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); 
    }
  switch (is_syscall(instr))
    {
    case 0:  break; 
    case 1:  fprintf(fp,"   (syscall)"); break; 
    case 2:  fprintf(fp,"   (syscall32)"); break; 
    default: assert(0); 
    }
}

   
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, 
                         FILE *profile_info,   /* is non NULL only if 'profiling' is non 0  */ 
                         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%8ld |    odd_align",*offset_addr);
        }
      else if (car(code) == no_instr)
        {
        }
      else if (car(code) == initialization_address)
        {
           fprintf(fp,"\n%8ld |    initialization_address %d",*offset_addr,integer_value(init_addr_val)); 
        }
      else if (car(code) == variables_deletion_address)
        {
    fprintf(fp,"\n%8ld |    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%8ld |    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,profile_info,cdr(car(code)),offset_addr,init_addr_val,var_del_addr_val); 
        }
      else if (consp(car(code)) && (car(car(code)) == label || car(car(code)) == ret_point))
        {
          int i = integer_value(cdr(car(code)));

          if (i < 0 || i >= offsets_size)
            {
              fprintf(fp,"\n%8ld |  label %d (at offset ?)",*offset_addr,i); 
            }
          else
            {
              fprintf(fp,"\n%8ld |  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%8ld |    address %-10d  ('%s' in '%s' at line %d)",
                    *offset_addr,
                    integer_value(cdr(car(code))),
                    string_content(car(operations[opid].names)),
                    string_content(operations[opid].abs_file_path),
                    integer_value(operations[opid].line));
          else
            fprintf(fp,"\n%8ld |    address %-10d",
                    *offset_addr,
                    integer_value(cdr(car(code)))); 
        }
      else if (consp(car(code)) && car(car(code)) == push_addr)
        {
          U32 opid = get_op_id_from_label(cdr(car(code))); 
          if (opid)
            fprintf(fp,"\n%8ld |    push_addr %-10d  ('%s' in '%s' at line %d)",
                    *offset_addr,
                    integer_value(cdr(car(code))),
                    string_content(car(operations[opid].names)),
                    string_content(operations[opid].abs_file_path),
                    integer_value(operations[opid].line));
          else
            fprintf(fp,"\n%8ld |    push_addr %-10d",
                    *offset_addr,
                    integer_value(cdr(car(code)))); 
        }
      else if (consp(car(code)) && car(car(code)) == jmpf) /* (jmpf addr . k) */
        {
          U32 opid = get_op_id_from_label(cdr(car(code))); 
          if (opid)
            fprintf(fp,"\n%8ld |    jmpf %-10d %d ('%s' in '%s' at line %d)",
                    *offset_addr,
                    integer_value(second(car(code))),
                    integer_value(cdr2(car(code))),
                    string_content(car(operations[opid].names)),
                    string_content(operations[opid].abs_file_path),
                    integer_value(operations[opid].line));
          else
            fprintf(fp,"\n%8ld |    jmpf %-10d %d",
                    *offset_addr,
                    integer_value(second(car(code))),
                    integer_value(cdr2(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)))); 
          if (profiling)
            {
              fprintf (profile_info,"%10u %s\n",(unsigned)*offset_addr,string_content(cdr(car(code))));
            }
        }
      else if (consp(car(code)) && car(car(code)) == load_word32)
        {
          fprintf(fp,"\n%8ld |    load_word32 %d",*offset_addr,(int)cdr(car(code))); 
        }
      else if (consp(car(code)) && car(car(code)) == word_64)
        {
          Expr bigits = cdr(car(code)); 
          fprintf(fp,"\n%8ld |    word_64 %08x %08x",*offset_addr,car(bigits),cdr(bigits)); 
        }
      else if (consp(car(code)) && car(car(code)) == word_128)
        {
          Expr bigits = cdr(car(code)); 
          fprintf(fp,"\n%8ld |    word_128 %08x %08x %08x %08x",*offset_addr,
                 car(bigits),second(bigits),third(bigits),cdr3(bigits)); 
        }
      else if (consp(car(code)) && car(car(code)) == load_int_small)
        {
          Expr bigits = cdr(car(code)); 
          fprintf(fp,"\n%8ld |    load_int_small %d",*offset_addr,word32_value(bigits));
        }
      else if (consp(car(code)) && car(car(code)) == load_int_big)
        {
          Expr bigits = cdr(car(code)); 
          fprintf(fp,"\n%8ld |    load_int_big [%d 256-bigits] ",*offset_addr,length(bigits));
          while(consp(bigits))
            {
              fprintf(fp,"%03d ",integer_value(car(bigits)));
              bigits = cdr(bigits); 
            }
        }
      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%8ld |    ",*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%8ld |    ",*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"); 
}