Back to index

cell-binutils  2.17cvs20070401
Defines | Typedefs | Enumerations | Functions
vax.c File Reference
#include "gprof.h"
#include "search_list.h"
#include "source.h"
#include "symtab.h"
#include "cg_arcs.h"
#include "corefile.h"
#include "hist.h"

Go to the source code of this file.

Defines

#define CALLS   0xfb
#define PC   0xf

Typedefs

typedef enum static opermodes
Sym static indirectchild
operandenum 
vax_operandmode (unsigned char *)

Enumerations

enum  opermodes {
  literal, indexed, reg, regdef,
  autodec, autoinc, autoincdef, bytedisp,
  bytedispdef, worddisp, worddispdef, longdisp,
  longdispdef, immediate, absolute, byterel,
  bytereldef, wordrel, wordreldef, longrel,
  longreldef
}

Functions

static char * vax_operandname (operandenum)
static long vax_operandlength (unsigned char *)
static bfd_signed_vma vax_offset (unsigned char *)
void vax_find_call (Sym *, bfd_vma, bfd_vma)
static operandenum vax_operandmode (unsigned char *modep)

Define Documentation

#define CALLS   0xfb

Definition at line 40 of file vax.c.

#define PC   0xf

Definition at line 45 of file vax.c.


Typedef Documentation

typedef enum static opermodes Sym static indirectchild operandenum vax_operandmode(unsigned char *) [static]

Definition at line 73 of file vax.c.


Enumeration Type Documentation

enum opermodes
Enumerator:
literal 
indexed 
reg 
regdef 
autodec 
autoinc 
autoincdef 
bytedisp 
bytedispdef 
worddisp 
worddispdef 
longdisp 
longdispdef 
immediate 
absolute 
byterel 
bytereldef 
wordrel 
wordreldef 
longrel 
longreldef 

Definition at line 47 of file vax.c.


Function Documentation

void vax_find_call ( Sym parent,
bfd_vma  p_lowpc,
bfd_vma  p_highpc 
)

Definition at line 232 of file vax.c.

{
  unsigned char *instructp;
  long length;
  Sym *child;
  operandenum mode;
  operandenum firstmode;
  bfd_vma pc, destpc;
  static bfd_boolean inited = FALSE;

  if (!inited)
    {
      inited = TRUE;
      sym_init (&indirectchild);
      indirectchild.cg.prop.fract = 1.0;
      indirectchild.cg.cyc.head = &indirectchild;
    }

  if (core_text_space == 0)
    {
      return;
    }
  if (p_lowpc < s_lowpc)
    {
      p_lowpc = s_lowpc;
    }
  if (p_highpc > s_highpc)
    {
      p_highpc = s_highpc;
    }
  DBG (CALLDEBUG, printf ("[findcall] %s: 0x%lx to 0x%lx\n",
                       parent->name, (unsigned long) p_lowpc,
                       (unsigned long) p_highpc));
  for (pc = p_lowpc; pc < p_highpc; pc += length)
    {
      length = 1;
      instructp = ((unsigned char *) core_text_space
                 + pc - core_text_sect->vma);
      if ((*instructp & 0xff) == CALLS)
       {
         /*
          *    maybe a calls, better check it out.
          *      skip the count of the number of arguments.
          */
         DBG (CALLDEBUG,
              printf ("[findcall]\t0x%lx:calls", (unsigned long) pc));
         firstmode = vax_operandmode (instructp + length);
         switch (firstmode)
           {
           case literal:
           case immediate:
             break;
           default:
             goto botched;
           }
         length += vax_operandlength (instructp + length);
         mode = vax_operandmode (instructp + length);
         DBG (CALLDEBUG,
              printf ("\tfirst operand is %s", vax_operandname (firstmode));
              printf ("\tsecond operand is %s\n", vax_operandname (mode)));
         switch (mode)
           {
           case regdef:
           case bytedispdef:
           case worddispdef:
           case longdispdef:
           case bytereldef:
           case wordreldef:
           case longreldef:
             /*
              *    indirect call: call through pointer
              *      either  *d(r)   as a parameter or local
              *              (r)     as a return value
              *              *f      as a global pointer
              *      [are there others that we miss?,
              *       e.g. arrays of pointers to functions???]
              */
             arc_add (parent, &indirectchild, (unsigned long) 0);
             length += vax_operandlength (instructp + length);
             continue;
           case byterel:
           case wordrel:
           case longrel:
             /*
              *    regular pc relative addressing
              *      check that this is the address of
              *      a function.
              */
             destpc = pc + vax_offset (instructp + length);
             if (destpc >= s_lowpc && destpc <= s_highpc)
              {
                child = sym_lookup (&symtab, destpc);
                DBG (CALLDEBUG,
                     printf ("[findcall]\tdestpc 0x%lx",
                            (unsigned long) destpc);
                     printf (" child->name %s", child->name);
                     printf (" child->addr 0x%lx\n",
                            (unsigned long) child->addr);
                  );
                if (child->addr == destpc)
                  {
                    /*
                     *    a hit
                     */
                    arc_add (parent, child, (unsigned long) 0);
                    length += vax_operandlength (instructp + length);
                    continue;
                  }
                goto botched;
              }
             /*
              *    else:
              *      it looked like a calls,
              *      but it wasn't to anywhere.
              */
             goto botched;
           default:
           botched:
             /*
              *    something funny going on.
              */
             DBG (CALLDEBUG, printf ("[findcall]\tbut it's a botch\n"));
             length = 1;
             continue;
           }
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_signed_vma vax_offset ( unsigned char *  modep) [static]

Definition at line 211 of file vax.c.

{
  operandenum mode = vax_operandmode (modep);

  ++modep;                         /* skip over the mode */
  switch (mode)
    {
    default:
      fprintf (stderr, "[reladdr] not relative address\n");
      return 0;
    case byterel:
      return 1 + bfd_get_signed_8 (core_bfd, modep);
    case wordrel:
      return 2 + bfd_get_signed_16 (core_bfd, modep);
    case longrel:
      return 4 + bfd_get_signed_32 (core_bfd, modep);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long vax_operandlength ( unsigned char *  modep) [static]

Definition at line 174 of file vax.c.

{

  switch (vax_operandmode (modep))
    {
    case literal:
    case reg:
    case regdef:
    case autodec:
    case autoinc:
    case autoincdef:
      return 1;
    case bytedisp:
    case bytedispdef:
    case byterel:
    case bytereldef:
      return 2;
    case worddisp:
    case worddispdef:
    case wordrel:
    case wordreldef:
      return 3;
    case immediate:
    case absolute:
    case longdisp:
    case longdispdef:
    case longrel:
    case longreldef:
      return 5;
    case indexed:
      return 1 + vax_operandlength (modep + 1);
    }
  /* NOTREACHED */
  abort ();
}

Here is the caller graph for this function:

static operandenum vax_operandmode ( unsigned char *  modep) [static]

Definition at line 80 of file vax.c.

{
  int usesreg = *modep & 0xf;

  switch ((*modep >> 4) & 0xf)
    {
    case 0:
    case 1:
    case 2:
    case 3:
      return literal;
    case 4:
      return indexed;
    case 5:
      return reg;
    case 6:
      return regdef;
    case 7:
      return autodec;
    case 8:
      return usesreg != PC ? autoinc : immediate;
    case 9:
      return usesreg != PC ? autoincdef : absolute;
    case 10:
      return usesreg != PC ? bytedisp : byterel;
    case 11:
      return usesreg != PC ? bytedispdef : bytereldef;
    case 12:
      return usesreg != PC ? worddisp : wordrel;
    case 13:
      return usesreg != PC ? worddispdef : wordreldef;
    case 14:
      return usesreg != PC ? longdisp : longrel;
    case 15:
      return usesreg != PC ? longdispdef : longreldef;
    }
  /* NOTREACHED */
  abort ();
}
static char * vax_operandname ( operandenum  mode) [static]

Definition at line 121 of file vax.c.

{

  switch (mode)
    {
    case literal:
      return "literal";
    case indexed:
      return "indexed";
    case reg:
      return "register";
    case regdef:
      return "register deferred";
    case autodec:
      return "autodecrement";
    case autoinc:
      return "autoincrement";
    case autoincdef:
      return "autoincrement deferred";
    case bytedisp:
      return "byte displacement";
    case bytedispdef:
      return "byte displacement deferred";
    case byterel:
      return "byte relative";
    case bytereldef:
      return "byte relative deferred";
    case worddisp:
      return "word displacement";
    case worddispdef:
      return "word displacement deferred";
    case wordrel:
      return "word relative";
    case wordreldef:
      return "word relative deferred";
    case immediate:
      return "immediate";
    case absolute:
      return "absolute";
    case longdisp:
      return "long displacement";
    case longdispdef:
      return "long displacement deferred";
    case longrel:
      return "long relative";
    case longreldef:
      return "long relative deferred";
    }
  /* NOTREACHED */
  abort ();
}

Here is the caller graph for this function: