| | 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: |
| | 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 | |
| | 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 */ |
| | 71 | int is_master() const { return is_orig_; } |
| | 72 | |
| | 73 | /* get my name */ |
| | 74 | const char *get_name() const { return name_buf_; } |
| | 75 | |
| | 76 | /* get a pointer to my name buffer */ |
| | 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 */ |
| | 151 | CVmSrcfEntry *get_entry(size_t idx) const |
| | 152 | { return (idx < list_used_ ? list_[idx] : 0); } |
| | 153 | |
| | 154 | /* get the number of entries */ |
| | 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 */ |