Logo Search packages:      
Sourcecode: uncc version File versions  Download package

functions.c

/*
 * uncc - The ultimate C decompiler
 * Copyright (C) 2003  Megabug <megabug@autistici.org>,
 *                     Little-John <littlejohn@autistici.org>
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 */

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

#include "functions.h"
#include "expressions.h"
#include "labels.h"

static Function *functions = NULL;

void FUNCTIONS_add(Function *f)
{
      f->next=functions;
      functions=f;
}

Function *FUNCTIONS_new_from_label(Label *l)
{
      Function *f;
      f = (Function *) malloc( sizeof(Function) );
      f->label = l;
      f->localvars = NULL;
      f->body = f->body_last = NULL;
      f->frame_size = 0;
      f->frame_pointer = NULL;
      f->external = 0;
      FUNCTIONS_add(f);
      return f;
}

Function *FUNCTIONS_find_from_label(Label *l)
{
      Function *i;
      for (i=functions; i; i=i->next)
            if (i->label==l)
                  return i;
      return NULL;
}

Label *FUNCTIONS_get_label(Function *f)
{     return f->label; }

char *FUNCTIONS_name(Function *f)
{
      return LABELS_name(f->label);
}

void FUNCTIONS_add_localvar(Function *f, Variable *v)
{
      v->next = f->localvars;
      f->localvars = v;
}

Variable *FUNCTIONS_new_localvar(Function *f, int offset, VarType vartype)
{
      Variable *var;
      char temp[30];
      static int counter=0;

      var=(Variable *)malloc(sizeof(Variable));
      sprintf(temp, "local%d", counter++);
      var->name=strdup(temp);
      var->offset=offset;
      var->type=vartype;
      FUNCTIONS_add_localvar(f, var);

      return var;
}

Variable *FUNCTIONS_find_localvar(Function *f, int offset, VarType vartype)
{
      Variable *i;
      for (i=f->localvars; i!=NULL; i=i->next)
            if (i->offset==offset && i->type==vartype)
                  return i;
      return NULL;
}

Variable *FUNCTIONS_find_or_new_localvar(Function *f, int offset, VarType vartype)
{
      Variable *g;
      g = FUNCTIONS_find_localvar(f, offset, vartype);
      if (!g) return FUNCTIONS_new_localvar(f, offset, vartype);
      return g;
}

void FUNCTIONS_add_argument(Function *f, Variable *v)
{
      v->next = f->arguments;
      f->arguments = v;
}

Variable *FUNCTIONS_new_argument(Function *f, int offset, VarType vartype)
{
      Variable *var;
      char temp[30];
      static int counter=0;

      var=(Variable *)malloc(sizeof(Variable));
      sprintf(temp, "arg%d", counter++);
      var->offset=offset;
      var->name=strdup(temp);
      var->type=vartype;
      FUNCTIONS_add_argument(f, var);

      return var;
}

Variable *FUNCTIONS_find_argument(Function *f, int offset, VarType vartype)
{
      Variable *i;
      for (i=f->arguments; i!=NULL; i=i->next)
            if (i->offset==offset && i->type==vartype)
                  return i;
      return NULL;
}

Variable *FUNCTIONS_find_or_new_argument(Function *f, int offset, VarType vartype)
{
      Variable *i;
      i=FUNCTIONS_find_argument(f,offset,vartype);
      if (!i) return FUNCTIONS_new_argument(f,offset,vartype);
      return i;
}

int FUNCTIONS_count_arguments(Function *f)
{
      Variable *i;
      int count=0;
      for (i=f->arguments; i; i=i->next)
            count++;
      return count;
}

void FUNCTIONS_sort_arguments_one(Function *f)
{
      Variable *i;
      if (f->arguments==NULL) return;
      if (f->arguments->next==NULL) return;

      for (i=f->arguments; i->next!=NULL; i=i->next)
            if ( i->offset > i->next->offset )
            {
                  Variable t;
                  Variable *a=i->next;
                  Variable *b=a->next;
                  memcpy(&t, i, sizeof(Variable));
                  memcpy(i, a, sizeof(Variable));
                  memcpy(a, &t, sizeof(Variable));
                  i->next=a;
                  a->next=b;
            }
}

void FUNCTIONS_set_frame_pointer(Function *f, Register *r)
{     f->frame_pointer = r; }

Register *FUNCTIONS_get_frame_pointer(Function *f)
{     return f->frame_pointer; }

void FUNCTIONS_sort_arguments()
{
      Function *i;
      for (i=functions; i; i=i->next)
            FUNCTIONS_sort_arguments_one(i);
}
      
Variable *FUNCTIONS_find_var(Function *f, int offset, VarType vartype)
{
      Variable *v;
      v = FUNCTIONS_find_localvar(f,offset,vartype);
      if (!v)
            return FUNCTIONS_find_argument(f,offset,vartype);
      return v;
}

char *FUNCTIONS_var_name(Variable *v)
{
      return v->name;
}

void FUNCTIONS_add_body_line(Function *f, Expr *l)
{
      BodyLine *n = (BodyLine *) malloc(sizeof(BodyLine));
      n->line = l;
      n->next = NULL;
      
      if (f->body==NULL)
            f->body = n;
      else
            f->body_last->next = n;
      f->body_last = n;
}

char *FUNCTIONS_vttoa(VarType vt)
{
      switch(vt)
      {
            case VAR_BYTE:  return "uint8";
            case VAR_WORD:  return "uint16";
            case VAR_DWORD: return "uint32";
            case VAR_QUAD:  return "uint64";
            default:    return "unktype";
      };
}

void FUNCTIONS_print_one(Function *f, FILE *t)
{
      Variable *v;
      BodyLine *l;

      /* Print function prototype */
      fprintf( t, "%s(", LABELS_name(f->label) );
      for (v=f->arguments; v; v=v->next)
            fprintf( t, "%s %s %s", v==f->arguments ? "" : ",", FUNCTIONS_vttoa(v->type), v->name );
      fprintf( t, " )\n{\n" );

      /* Print local variables */
      for (v=f->localvars; v; v=v->next)
            fprintf( t, "%s %s;\n", FUNCTIONS_vttoa(v->type), v->name );

      /* Print function body */
      for (l=f->body; l; l=l->next)
      {
            EXPR_print_tree(l->line,t);
            if ( !EXPR_is_label(l->line) ) fprintf(t, ";");
            fprintf(t, "\n");
      }

      /* Close function */
      fprintf( t, "}\n\n" );
}

void FUNCTIONS_print(FILE *target)
{
      Function *i;
      for (i=functions; i; i=i->next)
            FUNCTIONS_print_one(i,target);
}

Function *FUNCTIONS_first()
{     return functions; }

Function *FUNCTIONS_next(Function *f)
{     return f->next; }


void FUNCTIONS_set_frame_size(Function *f, int size)
{
      f->frame_size = size;
}

int FUNCTIONS_get_frame_size(Function *f)
{     return f->frame_size; }


void FUNCTIONS_set_external(Function *f)
{     f->external = 1; }

void FUNCTIONS_unset_external(Function *f)
{     f->external = 0; }

int FUNCTIONS_is_external(Function *f)
{     return f->external; }


Generated by  Doxygen 1.6.0   Back to index