Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | # ========== Copyright Header Begin ========================================== |
2 | # | |
3 | # OpenSPARC T2 Processor File: Error.pm | |
4 | # Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | # 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | # | |
7 | # * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | # | |
9 | # This program is free software; you can redistribute it and/or modify | |
10 | # it under the terms of the GNU General Public License as published by | |
11 | # the Free Software Foundation; version 2 of the License. | |
12 | # | |
13 | # This program is distributed in the hope that it will be useful, | |
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | # GNU General Public License for more details. | |
17 | # | |
18 | # You should have received a copy of the GNU General Public License | |
19 | # along with this program; if not, write to the Free Software | |
20 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | # | |
22 | # For the avoidance of doubt, and except that if any non-GPL license | |
23 | # choice is available it will apply instead, Sun elects to use only | |
24 | # the General Public License version 2 (GPLv2) at this time for any | |
25 | # software where a choice of GPL license versions is made | |
26 | # available with the language indicating that GPLv2 or any later version | |
27 | # may be used, or where a choice of which version of the GPL is applied is | |
28 | # otherwise unspecified. | |
29 | # | |
30 | # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | # CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | # have any questions. | |
33 | # | |
34 | # ========== Copyright Header End ============================================ | |
35 | # -*- perl -*- | |
36 | ||
37 | package Midas::Error; | |
38 | ||
39 | use strict; | |
40 | ||
41 | use File::Basename; | |
42 | ||
43 | use Exporter; | |
44 | ||
45 | ||
46 | our $Prg = basename $0; | |
47 | our $ERR = "$Prg: FATAL ERROR"; | |
48 | ||
49 | our @ISA = qw(Exporter); | |
50 | ||
51 | our $Print_Errors = 1; | |
52 | ||
53 | # IMPORTANT! | |
54 | # The error codes need to be kept consistent with goldfinger/gf_error.h | |
55 | # since the error codes from goldfinger are passed through to midas! | |
56 | ||
57 | use constant M_NOERROR => 0; | |
58 | use constant M_MISC => 1; | |
59 | use constant M_CODE => 2; | |
60 | use constant M_DIR => 3; | |
61 | use constant M_FILE => 4; | |
62 | use constant M_CMDFAIL => 5; | |
63 | use constant M_SECSYNTAX => 6; | |
64 | use constant M_ATTRSYNTAX => 7; | |
65 | use constant M_MISSINGPARAM => 8; | |
66 | use constant M_ILLEGALPARAM => 9; | |
67 | use constant M_OUTOFRANGE => 10; | |
68 | use constant M_NOTNUM => 11; | |
69 | use constant M_VACOLLIDE => 12; | |
70 | use constant M_PACOLLIDE => 13; | |
71 | use constant M_DIRECTIVESYNTAX => 14; | |
72 | use constant M_GENFAIL => 15; | |
73 | use constant M_ASMFAIL => 16; | |
74 | use constant M_CCFAIL => 17; | |
75 | use constant M_LINKFAIL => 18; | |
76 | use constant M_CPPFAIL => 19; | |
77 | use constant M_M4FAIL => 20; | |
78 | use constant M_BADCONFIG => 21; | |
79 | use constant M_EVENTERR => 22; | |
80 | use constant M_ARGERR => 23; | |
81 | use constant M_NOSEC => 24; | |
82 | use constant M_BADTSB => 25; | |
83 | use constant M_BADALIGN => 26; | |
84 | use constant M_EMPTYSECTION => 27; | |
85 | use constant M_TSBSYNTAX => 28; | |
86 | use constant M_APPSYNTAX => 29; | |
87 | use constant M_MEMORY => 30; | |
88 | use constant M_GOLDFINGERPARSE => 31; | |
89 | use constant M_GOLDFINGERARG => 32; | |
90 | use constant M_ELF => 33; | |
91 | use constant M_BADLABEL => 34; | |
92 | use constant M_GOLDFINGERMISC => 35; | |
93 | use constant M_GOLDFINGERVERSION => 36; | |
94 | use constant M_DUPLICATETAG => 37; | |
95 | use constant M_BLOCKSYNTAX => 38; | |
96 | ||
97 | ||
98 | our %ERRCODES = | |
99 | ( | |
100 | M_NOERROR() => "M_NOERROR (#%d): No error.", | |
101 | M_MISC() => 'M_MISC (#%d): Miscellaneous error.', | |
102 | M_CODE() => 'M_CODE (#%d): Error in midas code.', | |
103 | M_DIR () => 'M_DIR (#%d): Directory error.', | |
104 | M_FILE() => 'M_FILE (#%d): File error.', | |
105 | M_CMDFAIL() => 'M_CMDFAIL (#%d): Command failed.', | |
106 | M_SECSYNTAX() => 'M_SECSYNTAX (#%d): Error in section syntax.', | |
107 | M_ATTRSYNTAX() => 'M_ATTRSYNTAX (#%d): Error in attr syntax.', | |
108 | M_MISSINGPARAM() => 'M_MISSINGPARAM (#%d): Missing parameter.', | |
109 | M_ILLEGALPARAM() => 'M_ILLEGALPARAM (#%d): Illegal parameter.', | |
110 | M_OUTOFRANGE() => 'M_OUTOFRANGE (#%d): Out of range.', | |
111 | M_NOTNUM() => 'M_NOTNUM (#%d): Not a number.', | |
112 | M_VACOLLIDE() => 'M_VACOLLIDE (#%d): VA collision.', | |
113 | M_PACOLLIDE() => 'M_PACOLLIDE (#%d): PA collision.', | |
114 | M_DIRECTIVESYNTAX() => 'M_DIRECTIVESYNTAX (#%d): Directive syntax error.', | |
115 | M_GENFAIL() => 'M_GENFAIL (#%d): File generation failed.', | |
116 | M_ASMFAIL() => 'M_ASMFAIL (#%d): Assembler failed.', | |
117 | M_CCFAIL() => 'M_CCFAIL (#%d): C compiler failed.', | |
118 | M_LINKFAIL() => 'M_LINKFAIL (#%d): Linker failed.', | |
119 | M_CPPFAIL() => 'M_CPPFAIL (#%d): CPP failed.', | |
120 | M_M4FAIL() => 'M_M4FAIL (#%d): M4 preprocessor failed.', | |
121 | M_BADCONFIG() => 'M_BADCONFIG (#%d): Bad configuration.', | |
122 | M_EVENTERR() => 'M_EVENTERR (#%d): Event parsing error.', | |
123 | M_ARGERR() => 'M_ARGERR (#%d): Argument error.', | |
124 | M_NOSEC() => 'M_NOSEC (#%d): Undefined section.', | |
125 | M_BADTSB() => 'M_BADTSB (#%d): Bad TSB.', | |
126 | M_BADALIGN() => 'M_BADALIGN (#%d): Bad Alignment.', | |
127 | M_EMPTYSECTION() => 'M_EMPTYSECTION (#%d): Empty section.', | |
128 | M_TSBSYNTAX() => 'M_TSBSYNTAX (#%d): Error in tsb syntax.', | |
129 | M_APPSYNTAX() => 'M_APPSYNTAX (#%d): Error in app syntax.', | |
130 | M_MEMORY() => 'M_MEMORY (#%d): Memory error.', | |
131 | M_GOLDFINGERPARSE() => 'M_GOLDFINGERPARSE (#%d): Goldfinger parse error.', | |
132 | M_GOLDFINGERARG() => 'M_GOLDFINGERARG (#%d): Goldfinger arg error.', | |
133 | M_ELF() => 'M_ELF (#%d): ELF error.', | |
134 | M_BADLABEL() => 'M_BADLABEL (#%d): Bad label.', | |
135 | M_GOLDFINGERMISC() => 'M_GOLDFINGERMISC (#%d): Uncategorized goldfinger error.', | |
136 | M_GOLDFINGERVERSION() => 'M_GOLDFINGERVERSION (#%d): Bad version of goldfinger', | |
137 | M_DUPLICATETAG() => 'M_DUPLICATETAG (#%d): Duplicate tags in TSB', | |
138 | M_BLOCKSYNTAX() => 'M_BLOCKSYNTAX (#%d): Error defining goldfinger BLOCK' | |
139 | ); | |
140 | ||
141 | our @Error_Codes = qw( | |
142 | M_NOERROR | |
143 | M_MISC | |
144 | M_CODE | |
145 | M_DIR | |
146 | M_FILE | |
147 | M_CMDFAIL | |
148 | M_SECSYNTAX | |
149 | M_ATTRSYNTAX | |
150 | M_MISSINGPARAM | |
151 | M_ILLEGALPARAM | |
152 | M_OUTOFRANGE | |
153 | M_NOTNUM | |
154 | M_VACOLLIDE | |
155 | M_PACOLLIDE | |
156 | M_DIRECTIVESYNTAX | |
157 | M_GENFAIL | |
158 | M_ASMFAIL | |
159 | M_CCFAIL | |
160 | M_LINKFAIL | |
161 | M_CPPFAIL | |
162 | M_M4FAIL | |
163 | M_BADCONFIG | |
164 | M_EVENTERR | |
165 | M_ARGERR | |
166 | M_NOSEC | |
167 | M_BADTSB | |
168 | M_BADALIGN | |
169 | M_EMPTYSECTION | |
170 | M_TSBSYNTAX | |
171 | M_APPSYNTAX | |
172 | M_MEMORY | |
173 | M_GOLDFINGERPARSE | |
174 | M_GOLDFINGERARG | |
175 | M_ELF | |
176 | M_BADLABEL | |
177 | M_GOLDFINGERMISC | |
178 | M_GOLDFINGERVERSION | |
179 | M_DUPLICATETAG | |
180 | M_BLOCKSYNTAX | |
181 | ); | |
182 | ||
183 | our @EXPORT = (qw( | |
184 | @Error_Codes | |
185 | %ERRCODES | |
186 | handle_error | |
187 | get_error_code | |
188 | init_error | |
189 | suppress_error_messages | |
190 | errcode_to_string | |
191 | ), @Error_Codes); | |
192 | ||
193 | ||
194 | ############################################################################### | |
195 | ||
196 | sub init_error { | |
197 | $Print_Errors = 1; | |
198 | } | |
199 | ||
200 | ############################################################################### | |
201 | ||
202 | sub suppress_error_messages { | |
203 | $Print_Errors = 0; | |
204 | } | |
205 | ||
206 | ############################################################################### | |
207 | ||
208 | sub errcode_to_string { | |
209 | my $code = shift; | |
210 | ||
211 | if(not exists $ERRCODES{$code}) { | |
212 | return "Invalid error code \"$code\""; | |
213 | } | |
214 | return sprintf $ERRCODES{$code}, $code; | |
215 | } | |
216 | ||
217 | ############################################################################### | |
218 | ||
219 | sub handle_error { | |
220 | my $errobj = shift; | |
221 | ||
222 | return 0 unless defined $errobj; | |
223 | return 0 unless $errobj; | |
224 | ||
225 | my ($pkg, $file, $line) = caller; | |
226 | print STDERR "$Prg: At pkg=$pkg, file=$file, line=$line\n" if $Print_Errors; | |
227 | ||
228 | if(not ref $errobj) { | |
229 | $errobj = Midas::Error->throw($errobj); | |
230 | } | |
231 | ||
232 | die "Unknown exception \"$errobj\"\n" unless $errobj->can('catch'); | |
233 | return $errobj->catch(); | |
234 | } | |
235 | ||
236 | ############################################################################### | |
237 | ||
238 | sub get_error_code { | |
239 | my $errobj = shift; | |
240 | ||
241 | return 0 unless defined $errobj; | |
242 | return 0 unless $errobj; | |
243 | return M_CODE unless ref $errobj; | |
244 | return M_CODE unless $errobj->can('catch'); | |
245 | return $errobj->{code}; | |
246 | } | |
247 | ||
248 | ############################################################################### | |
249 | ||
250 | sub throw { | |
251 | my $class = shift; | |
252 | my $msg = shift; | |
253 | my $code = shift; | |
254 | $code = M_MISC unless defined $code; | |
255 | ||
256 | $class = ref $class if ref $class; | |
257 | my $this = bless {}, $class; | |
258 | $this->{code} = $code; | |
259 | $this->{msg} = $msg; | |
260 | ||
261 | return $this; | |
262 | } | |
263 | ||
264 | ############################################################################### | |
265 | ||
266 | sub catch { | |
267 | my $this = shift; | |
268 | ||
269 | my $msg = $this->{msg}; | |
270 | ||
271 | $this->{code} = M_CODE unless exists $ERRCODES{$this->{code}}; | |
272 | my $codemsg = errcode_to_string($this->{code}); | |
273 | ||
274 | $msg = "$codemsg\n$msg"; | |
275 | ||
276 | my @lines = split /\n/, "$msg"; | |
277 | my $string = join "\n", map { "$ERR: $_" } @lines; | |
278 | ||
279 | print STDERR "$string\n" if $Print_Errors; | |
280 | ||
281 | return $this->{code}; | |
282 | } | |
283 | ||
284 | ############################################################################### | |
285 | 1; |