|
1 /* |
|
2 |
|
3 Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. |
|
4 |
|
5 This program is free software; you can redistribute it and/or modify it |
|
6 under the terms of version 2.1 of the GNU Lesser General Public License |
|
7 as published by the Free Software Foundation. |
|
8 |
|
9 This program is distributed in the hope that it would be useful, but |
|
10 WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
12 |
|
13 Further, this software is distributed without any warranty that it is |
|
14 free of the rightful claim of any third person regarding infringement |
|
15 or the like. Any license provided herein, whether implied or |
|
16 otherwise, applies only to this software file. Patent licenses, if |
|
17 any, provided herein do not apply to combinations of this program with |
|
18 other software, or any other product whatsoever. |
|
19 |
|
20 You should have received a copy of the GNU Lesser General Public |
|
21 License along with this program; if not, write the Free Software |
|
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, |
|
23 USA. |
|
24 |
|
25 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, |
|
26 Mountain View, CA 94043, or: |
|
27 |
|
28 http://www.sgi.com |
|
29 |
|
30 For further information regarding this notice, see: |
|
31 |
|
32 http://oss.sgi.com/projects/GenInfo/NoticeExplan |
|
33 |
|
34 */ |
|
35 |
|
36 |
|
37 |
|
38 #include "config.h" |
|
39 #include "dwarf_incl.h" |
|
40 #ifdef HAVE_ELF_H |
|
41 #include <elf.h> |
|
42 #endif |
|
43 |
|
44 #include <stdio.h> |
|
45 #include <sys/stat.h> |
|
46 #include <sys/types.h> |
|
47 #include <stdlib.h> |
|
48 |
|
49 /* Array to hold string representation of errors. Any time a |
|
50 define is added to the list in libdwarf.h, a string should be |
|
51 added to this Array |
|
52 */ |
|
53 |
|
54 const char *_dwarf_errmsgs[] = { |
|
55 |
|
56 "No error (0)\n", |
|
57 "DW_DLE_VMM 1 dwarf format/library version mismatch", |
|
58 "DW_DLE_MAP 2 memory map failure", |
|
59 "DW_DLE_LEE 3 libelf error", |
|
60 "DW_DLE_NDS 4 no debug section", |
|
61 "DW_DLE_NLS 5 no line section ", |
|
62 "DW_DLE_ID 6 invalid descriptor for query ", |
|
63 "DW_DLE_IOF 7 I/O failure ", |
|
64 "DW_DLE_MAF 8 memory allocation failure ", |
|
65 "DW_DLE_IA 9 invalid argument ", |
|
66 "DW_DLE_MDE 10 mangled debugging entry ", |
|
67 "DW_DLE_MLE 11 mangled line number entry ", |
|
68 "DW_DLE_FNO 12 file not open ", |
|
69 "DW_DLE_FNR 13 file not a regular file ", |
|
70 "DW_DLE_FWA 14 file open with wrong access ", |
|
71 "DW_DLE_NOB 15 not an object file ", |
|
72 "DW_DLE_MOF 16 mangled object file header ", |
|
73 "DW_DLE_EOLL 17 end of location list entries ", |
|
74 "DW_DLE_NOLL 18 no location list section ", |
|
75 "DW_DLE_BADOFF 19 Invalid offset ", |
|
76 "DW_DLE_EOS 20 end of section ", |
|
77 "DW_DLE_ATRUNC 21 abbreviations section appears truncated", |
|
78 "DW_DLE_BADBITC 22 Address size passed to dwarf bad", |
|
79 |
|
80 "DW_DLE_DBG_ALLOC 23 Unable to malloc a Dwarf_Debug structure", |
|
81 "DW_DLE_FSTAT_ERROR 24 The file fd passed to dwarf_init " |
|
82 "cannot be fstat()ed", |
|
83 "DW_DLE_FSTAT_MODE_ERROR 25 The file mode bits do not " |
|
84 "indicate that the file being opened via " |
|
85 "dwarf_init() is a normal file", |
|
86 "DW_DLE_INIT_ACCESS_WRONG 26 A call to dwarf_init had an " |
|
87 "access of other than DW_DLC_READ", |
|
88 "DW_DLE_ELF_BEGIN_ERROR 27 a call to " |
|
89 "elf_begin(... ELF_C_READ_MMAP... ) failed", |
|
90 "DW_DLE_ELF_GETEHDR_ERROR 28 a call to " |
|
91 "elf32_getehdr() or elf64_getehdr() failed", |
|
92 "DW_DLE_ELF_GETSHDR_ERROR 29 a call to " |
|
93 "elf32_getshdr() or elf64_getshdr() failed", |
|
94 "DW_DLE_ELF_STRPTR_ERROR 30 a call to " |
|
95 "elf_strptr() failed trying to get a section name", |
|
96 "DW_DLE_DEBUG_INFO_DUPLICATE 31 Only one .debug_info " |
|
97 "section is allowed", |
|
98 "DW_DLE_DEBUG_INFO_NULL 32 .debug_info section present but " |
|
99 "elf_getdata() failed or section is zero-length", |
|
100 "DW_DLE_DEBUG_ABBREV_DUPLICATE 33 Only one .debug_abbrev " |
|
101 "section is allowed", |
|
102 "DW_DLE_DEBUG_ABBREV_NULL 34 .debug_abbrev section present but " |
|
103 "elf_getdata() failed or section is zero-length", |
|
104 "DW_DLE_DEBUG_ARANGES_DUPLICATE 35 Only one .debug_aranges " |
|
105 "section is allowed", |
|
106 "DW_DLE_DEBUG_ARANGES_NULL 36 .debug_aranges section present but " |
|
107 "elf_getdata() failed or section is zero-length", |
|
108 "DW_DLE_DEBUG_LINE_DUPLICATE 37 Only one .debug_line " |
|
109 "section is allowed", |
|
110 "DW_DLE_DEBUG_LINE_NULL (38) .debug_line section present but " |
|
111 "elf_getdata() failed or section is zero-length", |
|
112 "DW_DLE_DEBUG_LOC_DUPLICATE (39) Only one .debug_loc " |
|
113 "section is allowed", |
|
114 "DW_DLE_DEBUG_LOC_NULL (40) .debug_loc section present but " |
|
115 "elf_getdata() failed or section is zero-length", |
|
116 "DW_DLE_DEBUG_MACINFO_DUPLICATE (41) Only one .debug_macinfo " |
|
117 "section is allowed", |
|
118 "DW_DLE_DEBUG_MACINFO_NULL (42) .debug_macinfo section present but " |
|
119 "elf_getdata() failed or section is zero-length", |
|
120 "DW_DLE_DEBUG_PUBNAMES_DUPLICATE (43) Only one .debug_pubnames " |
|
121 "section is allowed", |
|
122 "DW_DLE_DEBUG_PUBNAMES_NULL (44) .debug_pubnames section present but " |
|
123 "elf_getdata() failed or section is zero-length", |
|
124 "DW_DLE_DEBUG_STR_DUPLICATE (45) Only one .debug_str " |
|
125 "section is allowed", |
|
126 "DW_DLE_DEBUG_STR_NULL (46) .debug_str section present but " |
|
127 "elf_getdata() failed or section is zero-length", |
|
128 "DW_DLE_CU_LENGTH_ERROR (47)", |
|
129 "DW_DLE_VERSION_STAMP_ERROR (48)", |
|
130 "DW_DLE_ABBREV_OFFSET_ERROR (49)", |
|
131 "DW_DLE_ADDRESS_SIZE_ERROR (50)", |
|
132 "DW_DLE_DEBUG_INFO_PTR_NULL (51)", |
|
133 "DW_DLE_DIE_NULL (52)", |
|
134 "DW_DLE_STRING_OFFSET_BAD (53)", |
|
135 "DW_DLE_DEBUG_LINE_LENGTH_BAD (54)", |
|
136 "DW_DLE_LINE_PROLOG_LENGTH_BAD (55)", |
|
137 "DW_DLE_LINE_NUM_OPERANDS_BAD", |
|
138 "DW_DLE_LINE_SET_ADDR_ERROR", |
|
139 "DW_DLE_LINE_EXT_OPCODE_BAD", |
|
140 "DW_DLE_DWARF_LINE_NULL", |
|
141 "DW_DLE_INCL_DIR_NUM_BAD", |
|
142 "DW_DLE_LINE_FILE_NUM_BAD", |
|
143 "DW_DLE_ALLOC_FAIL", |
|
144 "DW_DLE_NO_CALLBACK_FUNC", |
|
145 "DW_DLE_SECT_ALLOC", |
|
146 "DW_DLE_FILE_ENTRY_ALLOC", |
|
147 "DW_DLE_LINE_ALLOC", |
|
148 "DW_DLE_FPGM_ALLOC", |
|
149 "DW_DLE_INCDIR_ALLOC", |
|
150 "DW_DLE_STRING_ALLOC", |
|
151 "DW_DLE_CHUNK_ALLOC", |
|
152 "DW_DLE_BYTEOFF_ERR", |
|
153 "DW_DLE_CIE_ALLOC", |
|
154 "DW_DLE_FDE_ALLOC", |
|
155 "DW_DLE_REGNO_OVFL", |
|
156 "DW_DLE_CIE_OFFS_ALLOC", |
|
157 "DW_DLE_WRONG_ADDRESS", |
|
158 "DW_DLE_EXTRA_NEIGHBORS", |
|
159 "DW_DLE_WRONG_TAG", |
|
160 "DW_DLE_DIE_ALLOC", |
|
161 "DW_DLE_PARENT_EXISTS", |
|
162 "DW_DLE_DBG_NULL", |
|
163 "DW_DLE_DEBUGLINE_ERROR", |
|
164 "DW_DLE_DEBUGFRAME_ERROR", |
|
165 "DW_DLE_DEBUGINFO_ERROR", |
|
166 "DW_DLE_ATTR_ALLOC", |
|
167 "DW_DLE_ABBREV_ALLOC", |
|
168 "DW_DLE_OFFSET_UFLW", |
|
169 "DW_DLE_ELF_SECT_ERR", |
|
170 "DW_DLE_DEBUG_FRAME_LENGTH_BAD", |
|
171 "DW_DLE_FRAME_VERSION_BAD", |
|
172 "DW_DLE_CIE_RET_ADDR_REG_ERROR", |
|
173 "DW_DLE_FDE_NULL", |
|
174 "DW_DLE_FDE_DBG_NULL", |
|
175 "DW_DLE_CIE_NULL", |
|
176 "DW_DLE_CIE_DBG_NULL", |
|
177 "DW_DLE_FRAME_TABLE_COL_BAD", |
|
178 "DW_DLE_PC_NOT_IN_FDE_RANGE", |
|
179 "DW_DLE_CIE_INSTR_EXEC_ERROR", |
|
180 "DW_DLE_FRAME_INSTR_EXEC_ERROR", |
|
181 "DW_DLE_FDE_PTR_NULL", |
|
182 "DW_DLE_RET_OP_LIST_NULL", |
|
183 "DW_DLE_LINE_CONTEXT_NULL", |
|
184 "DW_DLE_DBG_NO_CU_CONTEXT", |
|
185 "DW_DLE_DIE_NO_CU_CONTEXT", |
|
186 "DW_DLE_FIRST_DIE_NOT_CU", |
|
187 "DW_DLE_NEXT_DIE_PTR_NULL", |
|
188 "DW_DLE_DEBUG_FRAME_DUPLICATE Only one .debug_frame " |
|
189 "section is allowed", |
|
190 "DW_DLE_DEBUG_FRAME_NULL .debug_frame section present but " |
|
191 "elf_getdata() failed or section is zero-length", |
|
192 "DW_DLE_ABBREV_DECODE_ERROR", |
|
193 "DW_DLE_DWARF_ABBREV_NULL", |
|
194 "DW_DLE_ATTR_NULL", |
|
195 "DW_DLE_DIE_BAD", |
|
196 "DW_DLE_DIE_ABBREV_BAD", |
|
197 "DW_DLE_ATTR_FORM_BAD", |
|
198 "DW_DLE_ATTR_NO_CU_CONTEXT", |
|
199 "DW_DLE_ATTR_FORM_SIZE_BAD", |
|
200 "DW_DLE_ATTR_DBG_NULL", |
|
201 "DW_DLE_BAD_REF_FORM", |
|
202 "DW_DLE_ATTR_FORM_OFFSET_BAD", |
|
203 "DW_DLE_LINE_OFFSET_BAD", |
|
204 "DW_DLE_DEBUG_STR_OFFSET_BAD", |
|
205 "DW_DLE_STRING_PTR_NULL", |
|
206 "DW_DLE_PUBNAMES_VERSION_ERROR", |
|
207 "DW_DLE_PUBNAMES_LENGTH_BAD", |
|
208 "DW_DLE_GLOBAL_NULL", |
|
209 "DW_DLE_GLOBAL_CONTEXT_NULL", |
|
210 "DW_DLE_DIR_INDEX_BAD", |
|
211 "DW_DLE_LOC_EXPR_BAD", |
|
212 "DW_DLE_DIE_LOC_EXPR_BAD", |
|
213 "DW_DLE_ADDR_ALLOC", |
|
214 "DW_DLE_OFFSET_BAD", |
|
215 "DW_DLE_MAKE_CU_CONTEXT_FAIL", |
|
216 "DW_DLE_REL_ALLOC", |
|
217 "DW_DLE_ARANGE_OFFSET_BAD", |
|
218 "DW_DLE_SEGMENT_SIZE_BAD", |
|
219 "DW_DLE_ARANGE_LENGTH_BAD", |
|
220 "DW_DLE_ARANGE_DECODE_ERROR", |
|
221 "DW_DLE_ARANGES_NULL", |
|
222 "DW_DLE_ARANGE_NULL", |
|
223 "DW_DLE_NO_FILE_NAME", |
|
224 "DW_DLE_NO_COMP_DIR", |
|
225 "DW_DLE_CU_ADDRESS_SIZE_BAD", |
|
226 "DW_DLE_INPUT_ATTR_BAD", |
|
227 "DW_DLE_EXPR_NULL", |
|
228 "DW_DLE_BAD_EXPR_OPCODE", |
|
229 "DW_DLE_EXPR_LENGTH_BAD", |
|
230 "DW_DLE_MULTIPLE_RELOC_IN_EXPR", |
|
231 "DW_DLE_ELF_GETIDENT_ERROR", |
|
232 "DW_DLE_NO_AT_MIPS_FDE", |
|
233 "DW_DLE_NO_CIE_FOR_FDE", |
|
234 "DW_DLE_DIE_ABBREV_LIST_NULL", |
|
235 "DW_DLE_DEBUG_FUNCNAMES_DUPLICATE", |
|
236 "DW_DLE_DEBUG_FUNCNAMES_NULL .debug_funcnames section present but " |
|
237 "elf_getdata() failed or section is zero-length", |
|
238 "DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR", |
|
239 "DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD", |
|
240 "DW_DLE_FUNC_NULL", |
|
241 "DW_DLE_FUNC_CONTEXT_NULL", |
|
242 "DW_DLE_DEBUG_TYPENAMES_DUPLICATE", |
|
243 "DW_DLE_DEBUG_TYPENAMES_NULL .debug_typenames section present but " |
|
244 "elf_getdata() failed or section is zero-length", |
|
245 "DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR", |
|
246 "DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD", |
|
247 "DW_DLE_TYPE_NULL", |
|
248 "DW_DLE_TYPE_CONTEXT_NULL", |
|
249 "DW_DLE_DEBUG_VARNAMES_DUPLICATE", |
|
250 "DW_DLE_DEBUG_VARNAMES_NULL .debug_varnames section present but " |
|
251 "elf_getdata() failed or section is zero-length", |
|
252 "DW_DLE_DEBUG_VARNAMES_VERSION_ERROR", |
|
253 "DW_DLE_DEBUG_VARNAMES_LENGTH_BAD", |
|
254 "DW_DLE_VAR_NULL", |
|
255 "DW_DLE_VAR_CONTEXT_NULL", |
|
256 "DW_DLE_DEBUG_WEAKNAMES_DUPLICATE", |
|
257 "DW_DLE_DEBUG_WEAKNAMES_NULL .debug_weaknames section present but " |
|
258 "elf_getdata() failed or section is zero-length", |
|
259 |
|
260 "DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR", |
|
261 "DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD", |
|
262 "DW_DLE_WEAK_NULL", |
|
263 "DW_DLE_WEAK_CONTEXT_NULL (175)", |
|
264 "DW_DLE_LOCDESC_COUNT_WRONG (176)", |
|
265 "DW_DLE_MACINFO_STRING_NULL (177)", |
|
266 "DW_DLE_MACINFO_STRING_EMPTY (178)", |
|
267 "DW_DLE_MACINFO_INTERNAL_ERROR_SPACE (179)", |
|
268 "DW_DLE_MACINFO_MALLOC_FAIL (180)", |
|
269 "DW_DLE_DEBUGMACINFO_ERROR (181)", |
|
270 "DW_DLE_DEBUG_MACRO_LENGTH_BAD (182)", |
|
271 "DW_DLE_DEBUG_MACRO_MAX_BAD (183)", |
|
272 "DW_DLE_DEBUG_MACRO_INTERNAL_ERR (184)", |
|
273 "DW_DLE_DEBUG_MACRO_MALLOC_SPACE (185)", |
|
274 "DW_DLE_DEBUG_MACRO_INCONSISTENT (186)", |
|
275 "DW_DLE_DF_NO_CIE_AUGMENTATION(187)", |
|
276 "DW_DLE_DF_REG_NUM_TOO_HIGH(188)", |
|
277 "DW_DLE_DF_MAKE_INSTR_NO_INIT(189)", |
|
278 "DW_DLE_DF_NEW_LOC_LESS_OLD_LOC(190)", |
|
279 "DW_DLE_DF_POP_EMPTY_STACK(191)", |
|
280 "DW_DLE_DF_ALLOC_FAIL(192)", |
|
281 "DW_DLE_DF_FRAME_DECODING_ERROR(193)", |
|
282 "DW_DLE_DEBUG_LOC_SECTION_SHORT(194)", |
|
283 "DW_DLE_FRAME_AUGMENTATION_UNKNOWN(195)", |
|
284 "DW_DLA_PUBTYPE_CONTEXT(196)", |
|
285 "DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD(197)", |
|
286 "DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR(198)", |
|
287 "DW_DLE_DEBUG_PUBTYPES_DUPLICATE(199)", |
|
288 "DW_DLE_FRAME_CIE_DECODE_ERROR(200)", |
|
289 "DW_DLE_FRAME_REGISTER_UNREPRESENTABLE(201)", |
|
290 "DW_DLE_FRAME_REGISTER_COUNT_MISMATCH(202)", |
|
291 "DW_DLE_LINK_LOOP(203)", |
|
292 |
|
293 |
|
294 |
|
295 }; |
|
296 |
|
297 |
|
298 |
|
299 |
|
300 /* |
|
301 This function performs error handling as described in the |
|
302 libdwarf consumer document section 3. Dbg is the Dwarf_debug |
|
303 structure being processed. Error is a pointer to the pointer |
|
304 to the error descriptor that will be returned. Errval is an |
|
305 error code listed in dwarf_error.h. |
|
306 */ |
|
307 void |
|
308 _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Sword errval) |
|
309 { |
|
310 Dwarf_Error errptr; |
|
311 |
|
312 /* |
|
313 Allow NULL dbg on entry, since sometimes that can happen and we |
|
314 want to report the upper-level error, not this one. */ |
|
315 if (error != NULL) { |
|
316 |
|
317 /* |
|
318 If dbg is NULL, use the alternate error struct. However, |
|
319 this will overwrite the earlier error. */ |
|
320 if (dbg != NULL) { |
|
321 errptr = |
|
322 (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); |
|
323 if (errptr == NULL) { |
|
324 fprintf(stderr, |
|
325 "Could not allocate Dwarf_Error structure, " |
|
326 "abort() in libdwarf.\n"); |
|
327 abort(); |
|
328 } |
|
329 } else { |
|
330 /* We have no dbg to work with. dwarf_init failed. We hack |
|
331 up a special area. */ |
|
332 errptr = _dwarf_special_no_dbg_error_malloc(); |
|
333 if (errptr == NULL) { |
|
334 fprintf(stderr, |
|
335 "Could not allocate Dwarf_Error structure, " |
|
336 "abort() in libdwarf..\n"); |
|
337 abort(); |
|
338 } |
|
339 } |
|
340 |
|
341 errptr->er_errval = errval; |
|
342 *error = errptr; |
|
343 return; |
|
344 } |
|
345 |
|
346 if (dbg != NULL && dbg->de_errhand != NULL) { |
|
347 errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1); |
|
348 if (errptr == NULL) { |
|
349 fprintf(stderr, "Could not allocate Dwarf_Error structure," |
|
350 " abort() in libdwarf.\n"); |
|
351 abort(); |
|
352 } |
|
353 errptr->er_errval = errval; |
|
354 dbg->de_errhand(errptr, dbg->de_errarg); |
|
355 return; |
|
356 } |
|
357 fprintf(stderr, |
|
358 "abort() in libdwarf. No error argument, no handler.\n"); |
|
359 abort(); |
|
360 } |
|
361 |
|
362 |
|
363 Dwarf_Unsigned |
|
364 dwarf_errno(Dwarf_Error error) |
|
365 { |
|
366 if (error == NULL) { |
|
367 return (0); |
|
368 } |
|
369 |
|
370 return (error->er_errval); |
|
371 } |
|
372 |
|
373 |
|
374 /* |
|
375 */ |
|
376 char * |
|
377 dwarf_errmsg(Dwarf_Error error) |
|
378 { |
|
379 if (error == NULL) { |
|
380 return "Dwarf_Error is NULL"; |
|
381 } |
|
382 |
|
383 if (error->er_errval > (sizeof(_dwarf_errmsgs) / sizeof(char *))) { |
|
384 return "Dwarf_Error value out of range"; |
|
385 } |
|
386 |
|
387 return ((char *) _dwarf_errmsgs[error->er_errval]); |
|
388 } |