1 /**************************** error.cpp **********************************
2 * Author: Agner Fog
3 * Date created: 2006-07-15
4 * Last modified: 2017-10-18
5 * Project: objconv
6 * Module: error.cpp
7 * Description:
8 * Standard procedure for error reporting to stderr
9 *
10 * Copyright 2006-2017 GNU General Public License http://www.gnu.org/licenses
11 *****************************************************************************/
12
13 // Define this if you get problems:
14 // #define OBJCONV_ERROR_CPP 1
15
16
17 #include "stdafx.h"
18
19 #define MAX_ERROR_TEXT_LENGTH 1024 // Maximum length of error text including extra info
20
21
22 // Make and initialize error reporter object
23 CErrorReporter err;
24
25 SErrorText ErrorTexts[] = {
26 // Unknown error
27 {0, 2, "Unknown error number!"},
28
29 // Warning messages
30 {1001, 1, "Empty command line option"},
31 {1002, 1, "Unknown command line option: %s"},
32 {1003, 1, "Unknown warning/error number: %i"},
33 {1006, 1, "Nothing do do. Copying file unchanged"},
34 {1008, 1, "Converting COFF file to ELF and back again."},
35 {1009, 1, "Converting OMF file to COFF and back again."},
36 {1010, 1, "Section index and section-relative fixup not supported in ELF file. Probably a debug record"},
37 {1011, 1, "Converting Mach-O file to ELF and back again."},
38 {1020, 1, "Non-public symbol %s cannot be made weak"},
39 {1021, 1, "Non-public symbol %s cannot be made local"},
40 {1022, 1, "Non-public symbol %s cannot get an alias"},
41 {1023, 1, "External symbol %s made local. Access to this symbol will cause error"},
42 {1024, 1, "Cannot change prefix on name %s, not a symbol"},
43 {1029, 1, "Debug information may be incompatible"},
44 {1030, 1, "Exception information may be incompatible"},
45 {1031, 1, "Windows resource information not translated"},
46 {1032, 1, "More than one symbol table found in ELF file"},
47 {1033, 1, "Sorry, cannot currently make alias in dynamic symbol table. Symbol = %s"},
48 {1040, 1, "Name of section %s too long. Truncating to 16 characters"},
49 {1050, 0, "Position dependent references will not work in .so file. (First occurrence is symbol %s. This message can be turned off with -wd1050)"},
50 {1051, 1, "Weak public not supported in target file type, symbol %s"},
51 {1052, 1, "Indirect symbol index out of range"},
52 {1053, 1, "Common constant converted to public: %s"},
53 {1054, 1, "Cannot find import table"},
54 {1055, 1, "Communal section currently not supported by objconv. Section dropped"},
55 {1060, 1, "Different alignments specified for same segment, %s. Using highest alignment"},
56 {1061, 1, "Symbol %s has lazy binding"},
57 {1062, 1, "Symbol %s has unknown type"},
58 {1063, 1, "Gnu indirect function (CPU dispatcher) cannot be converted"},
59 {1101, 1, "Output file name should have extension .lib or .a"},
60 {1102, 1, "Library members have different type"},
61 {1103, 1, "Output file name ignored"},
62 {1104, 1, "Library member %s not found. Extraction failed"},
63 {1105, 1, "Library member %s not found. Deletion failed"},
64 {1106, 1, "Symbol %s not found. Modification of this symbol failed"},
65 {1107, 1, "Name of library member %s should have extension .o or .obj"},
66 {1108, 1, "Name of library member %s too long. Truncating to 15 characters"},
67 {1109, 1, "Library member %s has unknown type. Possibly alias record without code"},
68 {1150, 1, "Universal binary contains more than one component that can be converted. Specify desired word size or use lipo to extract desired component"},
69 {1151, 1, "Skipping component with wordsize %i"},
70
71 {1202, 1, "OMF Record checksum error"},
72 {1203, 1, "Unrecognized data in OMF subrecord"},
73 {1204, 1, "String too long building OMF file. Truncating to 255 characters: %s"},
74 {1205, 1, "Alignment by %i possibly not supported for OMF file. Using page alignment (256 or 4096 depending on system)"},
75 {1206, 1, "Stack segment ignored"},
76 {1207, 1, "Overlapping data"},
77 {1208, 1, "Back-patched code (possibly OK)"},
78 {1211, 1, "%i comment records ignored"},
79 {1212, 1, "Record type (%s) not supported"},
80 {1213, 1, "Hash table has %i occurrences of name %s"},
81 {1214, 1, "Symbol %s defined in both modules %s"},
82 {1215, 1, "More than 251 blocks required in symbol hash table. May fail with some linkers"},
83 {1300, 1, "File contains 32-bit absolute address. Must link with option -image_base %s -pagezero_size 1000"},
84 {1301, 1, "Image-relative address converted to absolute. Assumes image base = "},
85 {1302, 1, "64-bit relocation with arbitrary reference point converted to 32-bit self-relative. Will fail if offset is negative"},
86 {1303, 1, "Cannot find imported symbol"},
87 {1304, 1, "Unknown relocation address"},
88
89 // Error messages
90 {2001, 2, "No more than one input file and one output file can be specified"},
91 {2002, 2, "Word size (%i) not supported for output file"},
92 {2003, 2, "Only one output format option can be specified. Command line error at %s"},
93 {2004, 2, "Unknown command line option: %s"},
94 {2005, 2, "Input file and output file cannot have same name: %s"},
95 {2006, 2, "Unsupported file type for file %s: %s"},
96 {2007, 2, "Cannot dump and convert file in the same command"},
97 {2008, 2, "This option must have two symbol names: %s"},
98 {2009, 2, "This option must have one symbol name: %s"},
99 {2010, 2, "Sorry. Dump of file type %s is not supported"},
100 {2011, 2, "Sorry. Conversion of file type %s is not supported"},
101 {2012, 2, "Cannot convert from word size %i to word size %i"},
102 {2013, 2, "Sorry. Conversion of file type %s to %s is not supported"},
103 {2014, 2, "File contains information for .NET common language runtime. Cannot convert"},
104 {2015, 2, "More than one option specified for symbol %s"},
105 {2016, 2, "Index out of range"},
106 {2017, 2, "File name %s specified more than once"},
107 {2018, 2, "Unknown type 0x%X for file: %s"},
108 {2020, 2, "Overflow when converting value of symbol %s to 32 bits"},
109 {2021, 2, "File contains information for objective-C runtime code. Cannot convert"},
110 {2022, 2, "Cannot convert executable file"},
111
112 {2030, 2, "Unsupported relocation type (%i)"},
113 {2031, 2, "Relocated symbol not found"},
114 {2032, 2, "Relocation points outside segment"},
115 {2033, 2, "Error in ELF file. Record size not specified"},
116 {2034, 2, "Symbol table not found in ELF file"},
117 {2035, 2, "Pointer out of range in object file"},
118 {2036, 2, "Unknown section index in ELF file: %i"},
119 {2037, 2, "Symbol storage/binding type %i not supported"},
120 {2038, 2, "Symbol type %i not supported"},
121 {2040, 2, "Symbol table corrupt in object file"},
122 {2041, 2, "File has relocation of uninitialized data"},
123 {2042, 2, "Relocation to global offset table found. Cannot convert position-independent code"},
124 {2043, 2, "Relocation to procedure linkage table found. Cannot convert"},
125 {2044, 2, "Relocation relative to arbitrary reference point that cannot be converted"},
126 {2045, 2, "Unknown import table type"},
127 {2050, 2, "Inconsistent relocation record pair"},
128 {2051, 2, "Too many symbols for Mach-O file. Maximum = 16M"},
129 {2052, 2, "Unexpected data between symbol table and string table"},
130
131 {2103, 2, "Cannot read input file %s"},
132 {2104, 2, "Cannot write output file %s"},
133 {2105, 2, "Wrong size of file %s"},
134 {2107, 2, "Too many response files"},
135 {2110, 2, "COFF file section table corrupt"},
136 {2112, 2, "String table corrupt"},
137 {2114, 2, "This is an intermediate file for whole-program-optimization in Intel compiler"},
138 {2200, 2, "Weak public symbols not supported in this file format"},
139 {2202, 2, "Symbol name %s too long. Cannot change prefix"},
140 {2203, 2, "File name %s too long"},
141 {2210, 2, "File contains overlapping relocation sources"},
142 {2301, 2, "OMF Record extends beyond end of file"},
143 {2302, 2, "Fixup source extends beyond end of section"},
144 {2303, 2, "Too many symbols for OMF file. Index exceeds 32767"},
145 {2304, 2, "Word-size index exceeds 65535"},
146 {2305, 2, "%i Communal sections found. Currently not supported by Objconv"},
147 {2306, 2, "Segment size is 4 Gbytes"},
148 {2307, 2, "Segment address is absolute"},
149 {2308, 2, "Unknown alignment %i"},
150 {2309, 2, "Data outside bounds of segment %s"},
151 {2310, 2, "Iterated data outside bounds of segment"},
152 {2311, 2, "Relocation of iterated data not supported by objconv"},
153 {2312, 2, "FIXUPP record does not refer to data record"},
154 {2313, 2, "OMF file has compression of repeated relocation target (thread). This is not supported in objconv"},
155 {2314, 2, "Unknown relocation method T%i"},
156 {2315, 2, "Group-relative relocation to %s not supported"},
157 {2316, 2, "Incompatible relocation method: %s"},
158 {2317, 2, "Incompatible word size: %i"},
159 {2318, 2, "OMF file has compression of repeated communal data. This is not supported in objconv"},
160 {2320, 2, "Mixed 32-bit and 64-bit segments"},
161 {2321, 2, "Wrong record size found"},
162 {2330, 2, "Imagebase specified more than once"},
163 {2331, 2, "Imagebase must be divisible by page size 1000 (hexadecimal)"},
164 {2332, 2, "Imagebase must > 0 and < 80000000 (hexadecimal)"},
165
166 {2500, 2, "Library/archive file is corrupt"},
167 {2501, 2, "Cannot store file of type %s in library"},
168 {2502, 2, "Too many members in library"},
169 {2503, 2, "Output file name must be specified"},
170 {2504, 2, "Object file type (%s) does not match library"},
171 {2505, 2, "Object file word size (%i) does not match library"},
172 {2506, 2, "Overflow of buffer for library member names"},
173 {2507, 2, "%s is an import library. Cannot convert to static library"},
174 {2600, 2, "Library has more than one header"},
175 {2601, 2, "Library page size (%i) is not a power of 2"},
176 {2602, 2, "Library end record does not match dictionary offset in OMF library"},
177 {2603, 2, "Public name %s not found in hash table"},
178 {2605, 2, "Symbol hash table too big. Creation of library failed"},
179 {2606, 2, "Too many library members. Creation of library failed"},
180 {2610, 2, "Library end record not found"},
181 {2620, 2, "You need to extract library members before disassembling"},
182 {2621, 2, "Wrong output file type"},
183
184 {2701, 2, "Wrong number of members in universal binary (%i)"},
185
186 {3000, 1, "Internal error in opcode table"},
187 {3001, 1, "Internal error: Unknown register type 0x%X"},
188
189 // Fatal errors makes the program stop immediately:
190 {9000, 9, "Objconv program internal inconsistency"},
191 {9001, 9, "Objconv program has been compiled with wrong integer sizes"},
192 {9002, 9, "Objconv cannot run on machine with big-endian memory organization"},
193 {9003, 9, "Array index out of range"},
194 {9004, 9, "Cannot resize array of type CArrayBuf"},
195 {9005, 9, "Exceeding 1kb size limit while building OMF record"},
196 {9006, 9, "Memory allocation failed"},
197 {9007, 9, "Objcopy internal error in opcode map 0x%X"},
198
199 // Mark end of list
200 {9999, 9999, "End of error text list"}
201 };
202
203
204 // Constructor for CErrorReporter
CErrorReporter()205 CErrorReporter::CErrorReporter() {
206 NumErrors = NumWarnings = WorstError = 0;
207 MaxWarnings = 50; // Max number of warning messages to pring
208 MaxErrors = 50; // Max number of error messages to print
209 }
210
FindError(int ErrorNumber)211 SErrorText * CErrorReporter::FindError(int ErrorNumber) {
212 // Search for error in ErrorTexts
213 int e;
214 const int ErrorTextsLength = sizeof(ErrorTexts) / sizeof(ErrorTexts[0]);
215 for (e = 0; e < ErrorTextsLength; e++) {
216 if (ErrorTexts[e].ErrorNumber == ErrorNumber) return ErrorTexts + e;
217 }
218 // Error number not found
219 static SErrorText UnknownErr = ErrorTexts[0];
220 UnknownErr.ErrorNumber = ErrorNumber;
221 UnknownErr.Status = 0x102; // Unknown error
222 return &UnknownErr;
223 }
224
225
submit(int ErrorNumber)226 void CErrorReporter::submit(int ErrorNumber) {
227 // Print error message with no extra info
228 SErrorText * err = FindError(ErrorNumber);
229 HandleError(err, err->Text);
230 }
231
submit(int ErrorNumber,int extra)232 void CErrorReporter::submit(int ErrorNumber, int extra) {
233 // Print error message with extra numeric info
234 // ErrorTexts[ErrorNumber] must contain %i where extra is to be inserted
235 char text[MAX_ERROR_TEXT_LENGTH];
236 SErrorText * err = FindError(ErrorNumber);
237 sprintf(text, err->Text, extra);
238 HandleError(err, text);
239 }
240
submit(int ErrorNumber,int extra1,int extra2)241 void CErrorReporter::submit(int ErrorNumber, int extra1, int extra2) {
242 // Print error message with 2 extra numeric values inserted
243 // ErrorTexts[ErrorNumber] must contain two %i fields where extra numbers are to be inserted
244 char text[MAX_ERROR_TEXT_LENGTH];
245 SErrorText * err = FindError(ErrorNumber);
246 sprintf(text, err->Text, extra1, extra2);
247 HandleError(err, text);
248 }
249
submit(int ErrorNumber,char const * extra)250 void CErrorReporter::submit(int ErrorNumber, char const * extra) {
251 // Print error message with extra text info
252 // ErrorTexts[ErrorNumber] must contain %s where extra is to be inserted
253 char text[MAX_ERROR_TEXT_LENGTH];
254 SErrorText * err = FindError(ErrorNumber);
255 sprintf(text, err->Text, extra);
256 //strcpy (text, err->Text);
257 //strncat( text, extra, MAX_ERROR_TEXT_LENGTH/2);
258 HandleError(err, text);
259 }
260
submit(int ErrorNumber,char const * extra1,char const * extra2)261 void CErrorReporter::submit(int ErrorNumber, char const * extra1, char const * extra2) {
262 // Print error message with two extra text info fields
263 // ErrorTexts[ErrorNumber] must contain %s where extra texts are to be inserted
264 char text[MAX_ERROR_TEXT_LENGTH];
265 if (extra1 == 0) extra1 = "???"; if (extra2 == 0) extra2 = "???";
266 SErrorText * err = FindError(ErrorNumber);
267 sprintf(text, err->Text, extra1, extra2);
268 HandleError(err, text);
269 }
270
submit(int ErrorNumber,int extra1,char const * extra2)271 void CErrorReporter::submit(int ErrorNumber, int extra1, char const * extra2) {
272 // Print error message with two extra text fields inserted
273 // ErrorTexts[ErrorNumber] must contain %i and %s where extra texts are to be inserted
274 char text[MAX_ERROR_TEXT_LENGTH];
275 if (extra2 == 0) extra2 = "???";
276 SErrorText * err = FindError(ErrorNumber);
277 sprintf(text, err->Text, extra1, extra2);
278 HandleError(err, text);
279 }
280
HandleError(SErrorText * err,char const * text)281 void CErrorReporter::HandleError(SErrorText * err, char const * text) {
282 // HandleError is used by submit functions
283 // check severity
284 int severity = err->Status & 0x0F;
285 if (severity == 0) {
286 return; // Ignore message
287 }
288 if (severity > 1 && err->ErrorNumber > WorstError) {
289 // Store highest error number
290 WorstError = err->ErrorNumber;
291 }
292 if (severity == 1) {
293 // Treat message as warning
294 if (++NumWarnings > MaxWarnings) return; // Maximum number of warnings has been printed
295 // Treat message as warning
296 fprintf(stderr, "\nWarning %i: %s", err->ErrorNumber, text);
297 if (NumWarnings == MaxWarnings) {
298 // Maximum number reached
299 fprintf(stderr, "\nSupressing further warning messages");
300 }
301 }
302 else {
303 // Treat message as error
304 if (++NumErrors > MaxErrors) return; // Maximum number of warnings has been printed
305 fprintf(stderr, "\nError %i: %s", err->ErrorNumber, text);
306 if (NumErrors == MaxErrors) {
307 // Maximum number reached
308 fprintf(stderr, "\nSupressing further warning messages");
309 }
310 }
311 if (severity == 9) {
312 // Abortion required
313 fprintf(stderr, "\nAborting\n");
314 exit(err->ErrorNumber);
315 }
316 }
317
Number()318 int CErrorReporter::Number() {
319 // Get number of fatal errors
320 return NumErrors;
321 }
322
GetWorstError()323 int CErrorReporter::GetWorstError() {
324 // Get highest warning or error number encountered
325 return WorstError;
326 }
327
ClearError(int ErrorNumber)328 void CErrorReporter::ClearError(int ErrorNumber) {
329 // Ignore further occurrences of this error
330 int e;
331 const int ErrorTextsLength = sizeof(ErrorTexts) / sizeof(ErrorTexts[0]);
332 for (e = 0; e < ErrorTextsLength; e++) {
333 if (ErrorTexts[e].ErrorNumber == ErrorNumber) break;
334 }
335 if (e < ErrorTextsLength) {
336 ErrorTexts[e].Status = 0;
337 }
338 }
339