Added code to suppress "functions" that have aninvalid instruction
[dyninst.git] / paradynd / src / symtab.h
1 /*
2  *  Copyright 1993 Jeff Hollingsworth.  All rights reserved.
3  *
4  */
5
6 /*
7  * symtab.h - interface to generic symbol table.
8  *
9  * $Log: symtab.h,v $
10  * Revision 1.8  1994/10/25 22:20:34  hollings
11  * Added code to suppress "functions" that have aninvalid instruction
12  * as their first instruction.  These are really read-only data that has
13  * been placed in the text segment to protect it from writing.
14  *
15  * Revision 1.7  1994/09/30  19:47:17  rbi
16  * Basic instrumentation for CMFortran
17  *
18  * Revision 1.6  1994/09/22  02:26:56  markc
19  * Made structs classes
20  *
21  * Revision 1.5  1994/08/02  18:25:08  hollings
22  * fixed modules to use list template for lists of functions.
23  *
24  * Revision 1.4  1994/07/22  19:21:11  hollings
25  * removed mistaken divid by 1Meg for predicted cost.
26  *
27  * Revision 1.3  1994/07/20  23:23:43  hollings
28  * added insn generated metric.
29  *
30  * Revision 1.2  1994/06/29  02:52:52  hollings
31  * Added metricDefs-common.{C,h}
32  * Added module level performance data
33  * cleanedup types of inferrior addresses instrumentation defintions
34  * added firewalls for large branch displacements due to text+data over 2meg.
35  * assorted bug fixes.
36  *
37  * Revision 1.1  1994/01/27  20:31:46  hollings
38  * Iinital version of paradynd speaking dynRPC igend protocol.
39  *
40  * Revision 1.4  1993/12/13  19:58:12  hollings
41  * added sibling filed for functions that occur multiple times in the same
42  * binary image (statics, and c++ template classes for example).
43  *
44  * Revision 1.3  1993/07/13  18:33:11  hollings
45  * new include file syntax.
46  *
47  * Revision 1.2  1993/06/08  20:14:34  hollings
48  * state prior to bc net ptrace replacement.
49  *
50  * Revision 1.1  1993/03/19  22:51:05  hollings
51  * Initial revision
52  *
53  *
54  */
55
56 extern "C" {
57 #include <sys/types.h>
58 #include <stdlib.h>
59 }
60
61 #include "util/h/stringPool.h"
62 #include "util/h/list.h"
63 #include "dyninst.h"
64 #include "arch-sparc.h"
65 #include "util.h"
66
67 /*
68  * List of supported languages.
69  *
70  */
71 typedef enum { unknown, assembly, C, cPlusPlus, gnuCPlusPlus,
72     fortran, CMFortran } supportedLanguages;
73
74 #define LIBRARY_MODULE  "LIBRARY_MODULE"
75 #define NO_SYMS_MODULE  "NO_SYMS_MODULE"
76
77 class pdFunction;
78 class instPoint;
79 class module;
80 class image;
81 class internalSym;
82
83 class pdFunction {
84  public:
85     pdFunction();
86     stringHandle symTabName;            /* name as it appears in the symbol table */
87     stringHandle prettyName;            /* user's view of name (i.e. de-mangled) */
88     int line;                   /* first line of function */
89     module *file;               /* pointer to file that defines func. */
90     caddr_t addr;               /* address of the start of the func */
91     instPoint *funcEntry;       /* place to instrument entry (often not addr) */
92     instPoint *funcReturn;      /* exit point for function */
93     int callLimit;              /* max val of calls array */
94     int callCount;              /* number of sub-routine cal points */
95     instPoint **calls;          /* pointer to the calls */
96     int ljmpCount;              /* number of long jumps out of func */
97     instPoint *jmps;            /* long jumps out */
98     int tag;                    /* tags to ident special (library) funcs. */
99     pdFunction *next;           /* next function in global function list */
100     pdFunction *sibling;                /* next function with the same name - WARNING
101                                         we assume name equality so this
102                                         could either be c++ template functions
103                                         beging replicated or other non global
104                                         functions that appear twice.
105                                 */
106 };
107
108
109 class instPoint {
110  public:
111     instPoint() {
112       addr = 0; originalInstruction.raw = 0; delaySlotInsn.raw = 0;
113       aggregateInsn.raw =0;
114       inDelaySlot=0; isDelayed = 0; callIndirect=0; callAggregate=0;
115       callee=NULL; func=NULL;
116     }
117     int addr;                   /* address of inst point */
118     instruction originalInstruction;    /* original instruction */
119     instruction delaySlotInsn;  /* original instruction */
120     instruction aggregateInsn;  /* aggregate insn */
121     int inDelaySlot;            /* Is the instruction in a dealy slot */
122     int isDelayed;              /* is the instruction a delayed instruction */
123     int callIndirect;           /* is it a call whose target is rt computed ? */
124     int callAggregate;          /* calling a func that returns an aggregate
125                                    we need to reolcate three insns in this case
126                                  */
127     pdFunction *callee;         /* what function is called */
128     pdFunction *func;           /* what function we are inst */
129 };
130
131
132 /* Stores source code to address in text association for modules */
133 class lineTable {
134  public:
135     lineTable() {
136       maxLine = 100;
137       addr = (caddr_t *) xcalloc(100, sizeof(caddr_t));
138     }
139     ~lineTable() {
140       if (addr)
141         free(addr);
142     }
143     void qsortLines() {
144       qsort(addr, maxLine, sizeof(int), intComp);
145     }
146     int getMaxLine() { return maxLine;}
147     void setLineAddr (int line, caddr_t lineAddr);
148     caddr_t getLineAddr (int line) {
149       if ((line >= 0) && (line < maxLine))
150         return (addr[line]);
151       else
152         return (NULL);
153     }
154
155   private:
156     int maxLine;                /* max possible line */
157     caddr_t *addr;              /* addr[line] is the addr of line */
158 };
159
160 class module {
161  public:
162     module();
163     void setLineAddr(int line, caddr_t addr) {
164       lines.setLineAddr(line, addr);
165     }
166     caddr_t getLineAddr(int line) {
167       return (lines.getLineAddr(line));
168     }
169     char *compileInfo;
170     stringHandle fileName;              /* short file */
171     stringHandle fullName;              /* full path to file */
172     supportedLanguages language;
173     caddr_t addr;               /* starting address of module */
174     List<pdFunction*> funcs;    /* functions defined in this module */
175     image *exec;                /* what executable it came from */
176     lineTable lines;            /* line mapping info */
177     module *next;               /* pointer to next module */
178 };
179
180 /* contents of line number field if line is unknown */
181 #define UNKNOWN_LINE    0
182
183 #define TAG_LIB_FUNC    0x01
184 #define TAG_IO_FUNC     0x02
185 #define TAG_MSG_FUNC    0x04
186 #define TAG_SYNC_FUNC   0x08
187 #define TAG_CPU_STATE   0x10    /* does the func block waiting for ext. event */
188 #define TAG_NON_FUNC    0x20    /* has an invalid instruction at entry point */
189
190 /*
191  * symbols we need to find from our RTinst library.  This is how we know
192  *   were our inst primatives got loaded as well as the data space variables
193  *   we use to put counters/timers and inst trampolines.  An array of these
194  *   is placed in the image structure.
195  *
196  */
197 class internalSym {
198  public:
199     internalSym() { 
200       name = NULL; addr=0;
201     }
202     stringHandle name;          /* name as it appears in the symbol table. */
203     unsigned int addr;          /* absolute address of the symbol */
204 };
205
206 class image {
207  public:
208     image();
209     stringHandle file;          /* image file name */
210     stringHandle name;          /* filename part of file */
211     int moduleCount;            /* number of modules */
212     module *modules;            /* pointer to modules */
213     int funcCount;              /* number of functions */
214     pdFunction *funcs;          /* pointer to linked list of functions */
215     int iSymCount;              /* # of internal RTinst library symbols */
216     internalSym *iSyms;         /* internal RTinst library symbols */
217     void *code;                 /* pointer to code */
218     unsigned int textOffset;    /* base of where code is loaded */
219     int offset;                 /* offset of a.out in file */
220     HTable<pdFunction*> funcAddrHash; /* hash table to find functions by address */
221     image *next;                /* next in our list of images */
222     int symbolExists(const char *); /* Does the symbol exist in the image? */
223     void postProcess(const char *);              /* Load .pif file */
224 };
225
226
227 /*
228  * a definition of a library function that we may wish to identify.  This is
229  *   how we describe it to the symbol table parser, not how it appears in
230  *   the symbol table.  Library functions are placed in a pseudo module 
231  *   named LIBRARY_MODULE. 
232  *
233  */
234 image *parseImage(char *file, int offset);
235 module *newModule(image*, const char *currDir, const char *name, caddr_t addr);
236 pdFunction *newFunc(image*, module *, const char *name, int addr);
237 extern stringPool pool;
238
239 class libraryFunc {
240     public:
241         libraryFunc(const char *n, int t) {
242             name = pool.findAndAdd(n);
243             tags = t;
244         }
245         stringHandle name;
246         int tags;
247 };
248
249 /*
250  * Functions provided by machine/os/vendor specific files.
251  *
252  * iSym is the prefix to match on to find the callable inst functions.
253  *
254  */
255 /*
256 image *loadSymTable(const char *file, int offset, List<libraryFunc*> libraryFunctions, 
257                     const char **iSym);
258 */
259 Boolean locateAllInstPoints(image *i);
260
261 /*
262  * main interface to the symbol table based code.
263  *
264  */
265 image *parseImage(char *file, int offset);
266
267 /*
268  * symbol table access functions.
269  *
270  */
271
272 /* find the named internal symbol */
273 internalSym *findInternalSymbol(image *, const char *name, Boolean warn = True);
274
275 /* find the address of the named internal symbol */
276 caddr_t findInternalAddress(image *, const char *name, Boolean warn = True);
277
278 /* find the named module */
279 module *findModule(image *, const char *name);
280
281 /* find the named funcation */
282 pdFunction *findFunction(image *, const char *name);
283
284 /* find the function add the passed addr */
285 pdFunction *findFunctionByAddr(image *, caddr_t addr);
286
287 /* look through func for inst points */
288 void locateInstPoints(pdFunction*, void *, int, int calls);
289
290 /* record line # for each func entry */
291 void mapLines(module *);