1 /* $Header$ */
2 
3 /*
4  *   Copyright (c) 1999, 2002 Michael J. Roberts.  All Rights Reserved.
5  *
6  *   Please see the accompanying license file, LICENSE.TXT, for information
7  *   on using and copying this software.
8  */
9 /*
10 Name
11   vmsrcf.h - T3 VM source file table
12 Function
13   Maintains a list of the source file records found in the "SRCF" block
14   in the image file
15 Notes
16 
17 Modified
18   12/01/99 MJRoberts  - Creation
19 */
20 
21 #ifndef VMSRCF_H
22 #define VMSRCF_H
23 
24 #include "t3std.h"
25 
26 /*
27  *   Source file line record
28  */
29 struct CVmSrcfLine
30 {
31     /* line number in source file */
32     ulong linenum;
33 
34     /* code address of generated code for source line */
35     ulong code_addr;
36 };
37 
38 /*
39  *   Source file entry
40  */
41 class CVmSrcfEntry
42 {
43 public:
CVmSrcfEntry(int orig_index,int is_orig,size_t name_len)44     CVmSrcfEntry(int orig_index, int is_orig, size_t name_len)
45     {
46         /* no source lines yet */
47         lines_ = 0;
48         lines_cnt_ = lines_alo_ = 0;
49 
50         /* set the original index */
51         orig_index_ = orig_index;
52 
53         /* remember whether this is the master entry */
54         is_orig_ = is_orig;
55 
56         /* allocate space for our name buffer */
57         name_buf_ = (char *)t3malloc(name_len + 1);
58     }
59 
~CVmSrcfEntry()60     ~CVmSrcfEntry()
61     {
62         /* delete our line records, if we have any */
63         if (lines_ != 0)
64             t3free(lines_);
65 
66         /* delete our name buffer */
67         t3free(name_buf_);
68     }
69 
70     /* determine if the entry is the master record */
is_master()71     int is_master() const { return is_orig_; }
72 
73     /* get my name */
get_name()74     const char *get_name() const { return name_buf_; }
75 
76     /* get a pointer to my name buffer */
get_name_buf()77     char *get_name_buf() { return name_buf_; }
78 
79     /*
80      *   allocate space for source line entries - this can be used to
81      *   pre-allocate space if the number of line entries is known in
82      *   advance
83      */
84     void alloc_line_records(ulong cnt);
85 
86     /*
87      *   Add a source line entry.  Line entries must be added in ascending
88      *   order of line number.
89      */
90     void add_line_record(ulong linenum, ulong code_addr);
91 
92     /*
93      *   Find the code address for a given source line.  Returns zero if
94      *   we are unsuccessful, non-zero if successful (an executable line
95      *   can never have a source address equal to zero, since if a method
96      *   is at such a low address at all, its header would take up the
97      *   first few bytes, putting the first executable instruction at a
98      *   non-zero address).
99      *
100      *   If 'exact' is true, we'll fail unless we find an exact match;
101      *   otherwise, we'll return the code address for the next executable
102      *   line after the given line, or the last executable line in the
103      *   file if there are no more executable lines after the given line.
104      *
105      *   If we find a non-exact match, we'll update *linenum to give the
106      *   actual line number where we found the executable line.
107      */
108     ulong find_src_addr(ulong *linenum, int exact);
109 
110 private:
111     /* name buffer */
112     char *name_buf_;
113 
114     /* index of original entry for this filename */
115     int orig_index_;
116 
117     /* flag: I'm the original entry */
118     uint is_orig_ : 1;
119 
120     /*
121      *   Line records array.  For simplicity, this is simply a single
122      *   array.  This could be a little constraining for 16-bit machines,
123      *   but even on a 16-bit machine, this will accommodate 8000 records,
124      *   which should be enough for even fairly large source files.
125      */
126     CVmSrcfLine *lines_;
127 
128     /* number of line records actually in use */
129     ulong lines_cnt_;
130 
131     /* number of lines allocated */
132     ulong lines_alo_;
133 };
134 
135 /*
136  *   Source file table
137  */
138 class CVmSrcfTable
139 {
140 public:
141     CVmSrcfTable();
142     ~CVmSrcfTable();
143 
144     /* clear the table */
145     void clear();
146 
147     /* add a new entry */
148     CVmSrcfEntry *add_entry(int orig_index, size_t name_len);
149 
150     /* get an entry given the 0-based index */
get_entry(size_t idx)151     CVmSrcfEntry *get_entry(size_t idx) const
152         { return (idx < list_used_ ? list_[idx] : 0); }
153 
154     /* get the number of entries */
get_count()155     size_t get_count() const { return list_used_; }
156 
157 private:
158     /* array of entries */
159     CVmSrcfEntry **list_;
160 
161     /* number of entries currently in use in the list */
162     size_t list_used_;
163 
164     /* number of entries allocated in the list */
165     size_t list_alloc_;
166 };
167 
168 #endif /* VMSRCF_H */
169