OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [binutils-2.18.50/] [gprof/] [alpha.c] - Blame information for rev 868

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/*
2
 * Copyright (c) 1983, 1993, 1998
3
 *      The Regents of the University of California.  All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the University nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29
#include "gprof.h"
30
#include "search_list.h"
31
#include "source.h"
32
#include "symtab.h"
33
#include "cg_arcs.h"
34
#include "corefile.h"
35
#include "hist.h"
36
 
37
/*
38
 * Opcodes of the call instructions:
39
 */
40
#define OP_Jxx  0x1a
41
#define OP_BSR  0x34
42
 
43
#define Jxx_FUNC_JMP            0
44
#define Jxx_FUNC_JSR            1
45
#define Jxx_FUNC_RET            2
46
#define Jxx_FUNC_JSR_COROUTINE  3
47
 
48
/* *INDENT-OFF* */
49
/* Here to document only.  We can't use this when cross compiling as
50
   the bitfield layout might not be the same as native.
51
 
52
   typedef union
53
     {
54
       struct
55
         {
56
           unsigned other:26;
57
           unsigned op_code:6;
58
         }
59
       a;                               -- any format
60
       struct
61
         {
62
           int disp:21;
63
           unsigned ra:5;
64
           unsigned op_code:6;
65
         }
66
       b;                               -- branch format
67
       struct
68
         {
69
           int hint:14;
70
           unsigned func:2;
71
           unsigned rb:5;
72
           unsigned ra:5;
73
           unsigned op_code:6;
74
         }
75
       j;                               -- jump format
76
     }
77
    alpha_Instruction;
78
*/
79
/* *INDENT-ON* */
80
 
81
static Sym indirect_child;
82
 
83
void alpha_find_call (Sym *, bfd_vma, bfd_vma);
84
 
85
/*
86
 * On the Alpha we can only detect PC relative calls, which are
87
 * usually generated for calls to functions within the same
88
 * object file only.  This is still better than nothing, however.
89
 * (In particular it should be possible to find functions that
90
 *  potentially call integer division routines, for example.)
91
 */
92
void
93
alpha_find_call (Sym *parent, bfd_vma p_lowpc, bfd_vma p_highpc)
94
{
95
  bfd_vma pc, dest_pc;
96
  unsigned int insn;
97
  Sym *child;
98
 
99
  if (indirect_child.name == NULL)
100
    {
101
      sym_init (&indirect_child);
102
      indirect_child.name = _("<indirect child>");
103
      indirect_child.cg.prop.fract = 1.0;
104
      indirect_child.cg.cyc.head = &indirect_child;
105
    }
106
 
107
  DBG (CALLDEBUG, printf (_("[find_call] %s: 0x%lx to 0x%lx\n"),
108
                          parent->name, (unsigned long) p_lowpc,
109
                          (unsigned long) p_highpc));
110
  for (pc = (p_lowpc + 3) & ~(bfd_vma) 3; pc < p_highpc; pc += 4)
111
    {
112
      insn = bfd_get_32 (core_bfd, ((unsigned char *) core_text_space
113
                                    + pc - core_text_sect->vma));
114
      switch (insn & (0x3f << 26))
115
        {
116
        case OP_Jxx << 26:
117
          /*
118
           * There is no simple and reliable way to determine the
119
           * target of a jsr (the hint bits help, but there aren't
120
           * enough bits to get a satisfactory hit rate).  Instead,
121
           * for any indirect jump we simply add an arc from PARENT
122
           * to INDIRECT_CHILD---that way the user it at least able
123
           * to see that there are other calls as well.
124
           */
125
          if ((insn & (3 << 14)) == Jxx_FUNC_JSR << 14
126
              || (insn & (3 << 14)) == Jxx_FUNC_JSR_COROUTINE << 14)
127
            {
128
              DBG (CALLDEBUG,
129
                   printf (_("[find_call] 0x%lx: jsr%s <indirect_child>\n"),
130
                           (unsigned long) pc,
131
                           ((insn & (3 << 14)) == Jxx_FUNC_JSR << 14
132
                            ? "" : "_coroutine")));
133
              arc_add (parent, &indirect_child, (unsigned long) 0);
134
            }
135
          break;
136
 
137
        case OP_BSR << 26:
138
          DBG (CALLDEBUG,
139
               printf (_("[find_call] 0x%lx: bsr"), (unsigned long) pc));
140
          /*
141
           * Regular PC relative addressing.  Check that this is the
142
           * address of a function.  The linker sometimes redirects
143
           * the entry point by 8 bytes to skip loading the global
144
           * pointer, so we allow for either address:
145
           */
146
          dest_pc = pc + 4 + (((bfd_signed_vma) (insn & 0x1fffff)
147
                               ^ 0x100000) - 0x100000);
148
          if (hist_check_address (dest_pc))
149
            {
150
              child = sym_lookup (&symtab, dest_pc);
151
              DBG (CALLDEBUG,
152
                   printf (" 0x%lx\t; name=%s, addr=0x%lx",
153
                           (unsigned long) dest_pc, child->name,
154
                           (unsigned long) child->addr));
155
              if (child->addr == dest_pc || child->addr == dest_pc - 8)
156
                {
157
                  DBG (CALLDEBUG, printf ("\n"));
158
                  /* a hit:  */
159
                  arc_add (parent, child, (unsigned long) 0);
160
                  continue;
161
                }
162
            }
163
          /*
164
           * Something funny going on.
165
           */
166
          DBG (CALLDEBUG, printf ("\tbut it's a botch\n"));
167
          break;
168
 
169
        default:
170
          break;
171
        }
172
    }
173
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.