|
1 /* |
|
2 |
|
3 Copyright (C) 2000,2002,2003,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 #if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) ) |
|
38 #endif |
|
39 |
|
40 #include "config.h" |
|
41 #include "dwarf_incl.h" |
|
42 #ifdef HAVE_ELF_H |
|
43 #include <elf.h> |
|
44 #endif |
|
45 #ifdef __SGI_FAST_LIBELF |
|
46 #include <libelf_sgi.h> |
|
47 #else |
|
48 #ifdef HAVE_LIBELF_H |
|
49 #include <libelf.h> |
|
50 #else |
|
51 #ifdef HAVE_LIBELF_LIBELF_H |
|
52 #include <libelf/libelf.h> |
|
53 #endif |
|
54 #endif |
|
55 #endif /* !defined(__SGI_FAST_LIBELF) */ |
|
56 |
|
57 #include <stdio.h> |
|
58 #include <sys/stat.h> |
|
59 #include <sys/types.h> |
|
60 #include <string.h> |
|
61 #include <stdlib.h> |
|
62 |
|
63 #include "dwarf_incl.h" |
|
64 #include "malloc_check.h" |
|
65 |
|
66 #define DWARF_DBG_ERROR(dbg,errval,retval) \ |
|
67 _dwarf_error(dbg, error, errval); return(retval); |
|
68 |
|
69 #define FALSE 0 |
|
70 #define TRUE 1 |
|
71 |
|
72 #ifdef __SGI_FAST_LIBELF |
|
73 #else |
|
74 #ifdef HAVE_ELF64_GETEHDR |
|
75 extern Elf64_Ehdr *elf64_getehdr(Elf *); |
|
76 #endif |
|
77 #ifdef HAVE_ELF64_GETSHDR |
|
78 extern Elf64_Shdr *elf64_getshdr(Elf_Scn *); |
|
79 #endif |
|
80 #endif /* !defined(__SGI_FAST_LIBELF) */ |
|
81 |
|
82 |
|
83 /* This static is copied to the dbg on dbg init |
|
84 so that the static need not be referenced at |
|
85 run time, preserving better locality of |
|
86 reference. |
|
87 Value is 0 means do the string check. |
|
88 Value non-zero means do not do the check. |
|
89 */ |
|
90 static Dwarf_Small _dwarf_assume_string_bad; |
|
91 |
|
92 |
|
93 int |
|
94 dwarf_set_stringcheck(int newval) |
|
95 { |
|
96 int oldval = _dwarf_assume_string_bad; |
|
97 |
|
98 _dwarf_assume_string_bad = newval; |
|
99 return oldval; |
|
100 } |
|
101 |
|
102 #ifdef __SGI_FAST_LIBELF |
|
103 /* |
|
104 This function translates an elf_sgi error code into a libdwarf |
|
105 code. |
|
106 */ |
|
107 static int |
|
108 _dwarf_error_code_from_elf_sgi_error_code(enum elf_sgi_error_type val) |
|
109 { |
|
110 switch (val) { |
|
111 case ELF_SGI_ERROR_OK: |
|
112 return DW_DLE_NE; |
|
113 case ELF_SGI_ERROR_BAD_ALLOC: |
|
114 return DW_DLE_MAF; |
|
115 case ELF_SGI_ERROR_FORMAT: |
|
116 return DW_DLE_MDE; |
|
117 case ELF_SGI_ERROR_ERRNO: |
|
118 return DW_DLE_IOF; |
|
119 case ELF_SGI_ERROR_TOO_BIG: |
|
120 return DW_DLE_MOF; |
|
121 default: |
|
122 return DW_DLE_LEE; |
|
123 } |
|
124 } |
|
125 #endif |
|
126 |
|
127 /* |
|
128 Given an Elf ptr, set up dbg with pointers |
|
129 to all the Dwarf data sections. |
|
130 Return NULL on error. |
|
131 |
|
132 This function is also responsible for determining |
|
133 whether the given object contains Dwarf information |
|
134 or not. The test currently used is that it contains |
|
135 either a .debug_info or a .debug_frame section. If |
|
136 not, it returns DW_DLV_NO_ENTRY causing dwarf_init() also to |
|
137 return DW_DLV_NO_ENTRY. Earlier, we had thought of using only |
|
138 the presence/absence of .debug_info to test, but we |
|
139 added .debug_frame since there could be stripped objects |
|
140 that have only a .debug_frame section for exception |
|
141 processing. |
|
142 DW_DLV_NO_ENTRY or DW_DLV_OK or DW_DLV_ERROR |
|
143 */ |
|
144 static int |
|
145 _dwarf_setup(Dwarf_Debug dbg, dwarf_elf_handle elf, Dwarf_Error * error) |
|
146 { |
|
147 #ifdef __SGI_FAST_LIBELF |
|
148 Elf64_Ehdr ehdr; |
|
149 Elf64_Shdr shdr; |
|
150 enum elf_sgi_error_type sres; |
|
151 unsigned char const *ehdr_ident = 0; |
|
152 #else |
|
153 Elf32_Ehdr *ehdr32 = 0; |
|
154 |
|
155 #ifdef HAVE_ELF64_GETEHDR |
|
156 Elf64_Ehdr *ehdr64 = 0; |
|
157 #endif |
|
158 Elf32_Shdr *shdr32 = 0; |
|
159 |
|
160 #ifdef HAVE_ELF64_GETSHDR |
|
161 Elf64_Shdr *shdr64 = 0; |
|
162 #endif |
|
163 Elf_Scn *scn = 0; |
|
164 char *ehdr_ident = 0; |
|
165 #endif /* !defined(__SGI_FAST_LIBELF) */ |
|
166 Dwarf_Half machine = 0; |
|
167 char *scn_name = 0; |
|
168 int is_64bit = 0; |
|
169 int foundDwarf = 0; |
|
170 |
|
171 Dwarf_Unsigned section_size = 0; |
|
172 Dwarf_Unsigned section_count = 0; |
|
173 Dwarf_Half section_index = 0; |
|
174 Dwarf_Addr section_addr = 0; |
|
175 |
|
176 foundDwarf = FALSE; |
|
177 dbg->de_elf = elf; |
|
178 |
|
179 dbg->de_assume_string_in_bounds = _dwarf_assume_string_bad; |
|
180 |
|
181 #ifdef __SGI_FAST_LIBELF |
|
182 sres = elf_sgi_ehdr(elf, &ehdr); |
|
183 if (sres != ELF_SGI_ERROR_OK) { |
|
184 DWARF_DBG_ERROR(dbg, |
|
185 _dwarf_error_code_from_elf_sgi_error_code(sres), |
|
186 DW_DLV_ERROR); |
|
187 } |
|
188 ehdr_ident = ehdr.e_ident; |
|
189 section_count = ehdr.e_shnum; |
|
190 machine = ehdr.e_machine; |
|
191 #else |
|
192 if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) { |
|
193 DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETIDENT_ERROR, DW_DLV_ERROR); |
|
194 } |
|
195 #endif |
|
196 |
|
197 is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64); |
|
198 |
|
199 |
|
200 dbg->de_same_endian = 1; |
|
201 dbg->de_copy_word = memcpy; |
|
202 #ifdef WORDS_BIGENDIAN |
|
203 dbg->de_big_endian_object = 1; |
|
204 if (ehdr_ident[EI_DATA] == ELFDATA2LSB) { |
|
205 dbg->de_same_endian = 0; |
|
206 dbg->de_big_endian_object = 0; |
|
207 dbg->de_copy_word = _dwarf_memcpy_swap_bytes; |
|
208 } |
|
209 #else /* little endian */ |
|
210 dbg->de_big_endian_object = 0; |
|
211 if (ehdr_ident[EI_DATA] == ELFDATA2MSB) { |
|
212 dbg->de_same_endian = 0; |
|
213 dbg->de_big_endian_object = 1; |
|
214 dbg->de_copy_word = _dwarf_memcpy_swap_bytes; |
|
215 } |
|
216 #endif /* !WORDS_BIGENDIAN */ |
|
217 |
|
218 /* The following de_length_size is Not Too Significant. Only used |
|
219 one calculation, and an approximate one at that. */ |
|
220 dbg->de_length_size = is_64bit ? 8 : 4; |
|
221 dbg->de_pointer_size = is_64bit ? 8 : 4; |
|
222 |
|
223 |
|
224 #ifdef __SGI_FAST_LIBELF |
|
225 /* We've already loaded the ELF header, so there's nothing to do |
|
226 here */ |
|
227 #else |
|
228 #ifdef HAVE_ELF64_GETEHDR |
|
229 if (is_64bit) { |
|
230 ehdr64 = elf64_getehdr(elf); |
|
231 if (ehdr64 == NULL) { |
|
232 DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR, |
|
233 DW_DLV_ERROR); |
|
234 } |
|
235 section_count = ehdr64->e_shnum; |
|
236 machine = ehdr64->e_machine; |
|
237 } else |
|
238 #endif |
|
239 { |
|
240 ehdr32 = elf32_getehdr(elf); |
|
241 if (ehdr32 == NULL) { |
|
242 DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR, |
|
243 DW_DLV_ERROR); |
|
244 } |
|
245 section_count = ehdr32->e_shnum; |
|
246 machine = ehdr32->e_machine; |
|
247 } |
|
248 #endif /* !defined(__SGI_FAST_LIBELF) */ |
|
249 |
|
250 if (is_64bit && machine != EM_MIPS) { |
|
251 /* MIPS/IRIX makes pointer size and length size 8 for -64. |
|
252 Other platforms make length 4 always. */ |
|
253 /* 4 here supports 32bit-offset dwarf2, as emitted by cygnus |
|
254 tools, and the dwarfv2.1 64bit extension setting. */ |
|
255 dbg->de_length_size = 4; |
|
256 } |
|
257 |
|
258 /* We start at index 1 to skip the initial empty section. */ |
|
259 for (section_index = 1; section_index < section_count; |
|
260 ++section_index) { |
|
261 |
|
262 #ifdef __SGI_FAST_LIBELF |
|
263 sres = elf_sgi_shdr(elf, section_index, &shdr); |
|
264 if (sres != ELF_SGI_ERROR_OK) { |
|
265 DWARF_DBG_ERROR(dbg, |
|
266 _dwarf_error_code_from_elf_sgi_error_code |
|
267 (sres), DW_DLV_ERROR); |
|
268 } |
|
269 |
|
270 section_size = shdr.sh_size; |
|
271 section_addr = shdr.sh_addr; |
|
272 |
|
273 sres = |
|
274 elf_sgi_string(elf, ehdr.e_shstrndx, shdr.sh_name, |
|
275 (char const **) &scn_name); |
|
276 if (sres != ELF_SGI_ERROR_OK) { |
|
277 DWARF_DBG_ERROR(dbg, |
|
278 _dwarf_error_code_from_elf_sgi_error_code |
|
279 (sres), DW_DLV_ERROR); |
|
280 } |
|
281 #else /* !defined(__SGI_FAST_LIBELF) */ |
|
282 scn = elf_getscn(elf, section_index); |
|
283 if (scn == NULL) { |
|
284 DWARF_DBG_ERROR(dbg, DW_DLE_MDE, DW_DLV_ERROR); |
|
285 } |
|
286 #ifdef HAVE_ELF64_GETSHDR |
|
287 if (is_64bit) { |
|
288 shdr64 = elf64_getshdr(scn); |
|
289 if (shdr64 == NULL) { |
|
290 DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR, |
|
291 DW_DLV_ERROR); |
|
292 } |
|
293 |
|
294 section_size = shdr64->sh_size; |
|
295 section_addr = shdr64->sh_addr; |
|
296 |
|
297 if ((scn_name = elf_strptr(elf, ehdr64->e_shstrndx, |
|
298 shdr64->sh_name)) |
|
299 == NULL) { |
|
300 DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR, |
|
301 DW_DLV_ERROR); |
|
302 } |
|
303 } else |
|
304 #endif /* HAVE_ELF64_GETSHDR */ |
|
305 { |
|
306 if ((shdr32 = elf32_getshdr(scn)) == NULL) { |
|
307 DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR, 0); |
|
308 } |
|
309 |
|
310 section_size = shdr32->sh_size; |
|
311 section_addr = shdr32->sh_addr; |
|
312 |
|
313 if ((scn_name = elf_strptr(elf, ehdr32->e_shstrndx, |
|
314 shdr32->sh_name)) == NULL) { |
|
315 DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR, |
|
316 DW_DLV_ERROR); |
|
317 } |
|
318 } |
|
319 #endif /* !defined(__SGI_FAST_LIBELF) */ |
|
320 |
|
321 if (strncmp(scn_name, ".debug_", 7) |
|
322 && strcmp(scn_name, ".eh_frame") |
|
323 ) |
|
324 continue; |
|
325 |
|
326 else if (strcmp(scn_name, ".debug_info") == 0) { |
|
327 if (dbg->de_debug_info != NULL) { |
|
328 DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_DUPLICATE, |
|
329 DW_DLV_ERROR); |
|
330 } |
|
331 if (section_size == 0) { |
|
332 /* Know no reason to allow empty debug_info section */ |
|
333 DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_NULL, |
|
334 DW_DLV_ERROR); |
|
335 } |
|
336 foundDwarf = TRUE; |
|
337 dbg->de_debug_info_index = section_index; |
|
338 dbg->de_debug_info_size = section_size; |
|
339 } |
|
340 |
|
341 else if (strcmp(scn_name, ".debug_abbrev") == 0) { |
|
342 if (dbg->de_debug_abbrev != NULL) { |
|
343 DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_DUPLICATE, |
|
344 DW_DLV_ERROR); |
|
345 } |
|
346 if (section_size == 0) { |
|
347 /* Know no reason to allow empty debug_abbrev section */ |
|
348 DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_NULL, |
|
349 DW_DLV_ERROR); |
|
350 } |
|
351 dbg->de_debug_abbrev_index = section_index; |
|
352 dbg->de_debug_abbrev_size = section_size; |
|
353 } |
|
354 |
|
355 else if (strcmp(scn_name, ".debug_aranges") == 0) { |
|
356 if (dbg->de_debug_aranges_index != 0) { |
|
357 DWARF_DBG_ERROR(dbg, |
|
358 DW_DLE_DEBUG_ARANGES_DUPLICATE, |
|
359 DW_DLV_ERROR); |
|
360 } |
|
361 if (section_size == 0) { |
|
362 /* a zero size section is just empty. Ok, no error */ |
|
363 continue; |
|
364 } |
|
365 dbg->de_debug_aranges_index = section_index; |
|
366 dbg->de_debug_aranges_size = section_size; |
|
367 } |
|
368 |
|
369 else if (strcmp(scn_name, ".debug_line") == 0) { |
|
370 if (dbg->de_debug_line_index != 0) { |
|
371 DWARF_DBG_ERROR(dbg, |
|
372 DW_DLE_DEBUG_LINE_DUPLICATE, |
|
373 DW_DLV_ERROR); |
|
374 } |
|
375 if (section_size == 0) { |
|
376 /* a zero size section is just empty. Ok, no error */ |
|
377 continue; |
|
378 } |
|
379 dbg->de_debug_line_index = section_index; |
|
380 dbg->de_debug_line_size = section_size; |
|
381 } |
|
382 |
|
383 else if (strcmp(scn_name, ".debug_frame") == 0) { |
|
384 if (dbg->de_debug_frame_index != 0) { |
|
385 DWARF_DBG_ERROR(dbg, |
|
386 DW_DLE_DEBUG_FRAME_DUPLICATE, |
|
387 DW_DLV_ERROR); |
|
388 } |
|
389 if (section_size == 0) { |
|
390 /* a zero size section is just empty. Ok, no error */ |
|
391 continue; |
|
392 } |
|
393 dbg->de_debug_frame_index = section_index; |
|
394 dbg->de_debug_frame_size = section_size; |
|
395 foundDwarf = TRUE; |
|
396 } else if (strcmp(scn_name, ".eh_frame") == 0) { |
|
397 /* gnu egcs-1.1.2 data */ |
|
398 if (dbg->de_debug_frame_eh_gnu_index != 0) { |
|
399 DWARF_DBG_ERROR(dbg, |
|
400 DW_DLE_DEBUG_FRAME_DUPLICATE, |
|
401 DW_DLV_ERROR); |
|
402 } |
|
403 if (section_size == 0) { |
|
404 /* a zero size section is just empty. Ok, no error */ |
|
405 continue; |
|
406 } |
|
407 dbg->de_debug_frame_eh_gnu_index = section_index; |
|
408 dbg->de_debug_frame_size_eh_gnu = section_size; |
|
409 dbg->de_debug_frame_eh_addr = section_addr; |
|
410 foundDwarf = TRUE; |
|
411 } |
|
412 |
|
413 else if (strcmp(scn_name, ".debug_loc") == 0) { |
|
414 if (dbg->de_debug_loc_index != 0) { |
|
415 DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_LOC_DUPLICATE, |
|
416 DW_DLV_ERROR); |
|
417 } |
|
418 if (section_size == 0) { |
|
419 /* a zero size section is just empty. Ok, no error */ |
|
420 continue; |
|
421 } |
|
422 dbg->de_debug_loc_index = section_index; |
|
423 dbg->de_debug_loc_size = section_size; |
|
424 } |
|
425 |
|
426 |
|
427 else if (strcmp(scn_name, ".debug_pubnames") == 0) { |
|
428 if (dbg->de_debug_pubnames_index != 0) { |
|
429 DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_PUBNAMES_DUPLICATE, |
|
430 DW_DLV_ERROR); |
|
431 } |
|
432 if (section_size == 0) { |
|
433 /* a zero size section is just empty. Ok, no error */ |
|
434 continue; |
|
435 } |
|
436 dbg->de_debug_pubnames_index = section_index; |
|
437 dbg->de_debug_pubnames_size = section_size; |
|
438 } |
|
439 |
|
440 else if (strcmp(scn_name, ".debug_str") == 0) { |
|
441 if (dbg->de_debug_str_index != 0) { |
|
442 DWARF_DBG_ERROR(dbg, |
|
443 DW_DLE_DEBUG_STR_DUPLICATE, |
|
444 DW_DLV_ERROR); |
|
445 } |
|
446 if (section_size == 0) { |
|
447 /* a zero size section is just empty. Ok, no error */ |
|
448 continue; |
|
449 } |
|
450 dbg->de_debug_str_index = section_index; |
|
451 dbg->de_debug_str_size = section_size; |
|
452 } |
|
453 |
|
454 else if (strcmp(scn_name, ".debug_funcnames") == 0) { |
|
455 if (dbg->de_debug_funcnames_index != 0) { |
|
456 DWARF_DBG_ERROR(dbg, |
|
457 DW_DLE_DEBUG_FUNCNAMES_DUPLICATE, |
|
458 DW_DLV_ERROR); |
|
459 } |
|
460 if (section_size == 0) { |
|
461 /* a zero size section is just empty. Ok, no error */ |
|
462 continue; |
|
463 } |
|
464 dbg->de_debug_funcnames_index = section_index; |
|
465 dbg->de_debug_funcnames_size = section_size; |
|
466 } |
|
467 |
|
468 else if (strcmp(scn_name, ".debug_typenames") == 0) { |
|
469 /* SGI IRIX-only, created years before DWARF3. Content |
|
470 essentially identical to .debug_pubtypes. */ |
|
471 if (dbg->de_debug_typenames_index != 0) { |
|
472 DWARF_DBG_ERROR(dbg, |
|
473 DW_DLE_DEBUG_TYPENAMES_DUPLICATE, |
|
474 DW_DLV_ERROR); |
|
475 } |
|
476 if (section_size == 0) { |
|
477 /* a zero size section is just empty. Ok, no error */ |
|
478 continue; |
|
479 } |
|
480 dbg->de_debug_typenames_index = section_index; |
|
481 dbg->de_debug_typenames_size = section_size; |
|
482 } else if (strcmp(scn_name, ".debug_pubtypes") == 0) { |
|
483 /* Section new in DWARF3. */ |
|
484 if (dbg->de_debug_pubtypes_index != 0) { |
|
485 DWARF_DBG_ERROR(dbg, |
|
486 DW_DLE_DEBUG_PUBTYPES_DUPLICATE, |
|
487 DW_DLV_ERROR); |
|
488 } |
|
489 if (section_size == 0) { |
|
490 /* a zero size section is just empty. Ok, no error */ |
|
491 continue; |
|
492 } |
|
493 dbg->de_debug_pubtypes_index = section_index; |
|
494 dbg->de_debug_pubtypes_size = section_size; |
|
495 } |
|
496 |
|
497 else if (strcmp(scn_name, ".debug_varnames") == 0) { |
|
498 if (dbg->de_debug_varnames_index != 0) { |
|
499 DWARF_DBG_ERROR(dbg, |
|
500 DW_DLE_DEBUG_VARNAMES_DUPLICATE, |
|
501 DW_DLV_ERROR); |
|
502 } |
|
503 if (section_size == 0) { |
|
504 /* a zero size section is just empty. Ok, no error */ |
|
505 continue; |
|
506 } |
|
507 dbg->de_debug_varnames_index = section_index; |
|
508 dbg->de_debug_varnames_size = section_size; |
|
509 } |
|
510 |
|
511 else if (strcmp(scn_name, ".debug_weaknames") == 0) { |
|
512 if (dbg->de_debug_weaknames_index != 0) { |
|
513 DWARF_DBG_ERROR(dbg, |
|
514 DW_DLE_DEBUG_WEAKNAMES_DUPLICATE, |
|
515 DW_DLV_ERROR); |
|
516 } |
|
517 if (section_size == 0) { |
|
518 /* a zero size section is just empty. Ok, no error */ |
|
519 continue; |
|
520 } |
|
521 dbg->de_debug_weaknames_index = section_index; |
|
522 dbg->de_debug_weaknames_size = section_size; |
|
523 } else if (strcmp(scn_name, ".debug_macinfo") == 0) { |
|
524 if (dbg->de_debug_macinfo_index != 0) { |
|
525 DWARF_DBG_ERROR(dbg, |
|
526 DW_DLE_DEBUG_MACINFO_DUPLICATE, |
|
527 DW_DLV_ERROR); |
|
528 } |
|
529 if (section_size == 0) { |
|
530 /* a zero size section is just empty. Ok, no error */ |
|
531 continue; |
|
532 } |
|
533 dbg->de_debug_macinfo_index = section_index; |
|
534 dbg->de_debug_macinfo_size = section_size; |
|
535 } |
|
536 } |
|
537 if (foundDwarf) { |
|
538 return DW_DLV_OK; |
|
539 } |
|
540 |
|
541 return (DW_DLV_NO_ENTRY); |
|
542 } |
|
543 |
|
544 |
|
545 /* |
|
546 The basic dwarf initializer function for consumers. |
|
547 Return NULL on error. |
|
548 */ |
|
549 int |
|
550 dwarf_init(int fd, |
|
551 Dwarf_Unsigned access, |
|
552 Dwarf_Handler errhand, |
|
553 Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error) |
|
554 { |
|
555 Dwarf_Debug dbg; |
|
556 struct stat fstat_buf; |
|
557 dwarf_elf_handle elf; |
|
558 int res; |
|
559 |
|
560 #ifdef __SGI_FAST_LIBELF |
|
561 enum elf_sgi_error_type sres; |
|
562 #else |
|
563 Elf_Cmd what_kind_of_elf_read; |
|
564 #endif |
|
565 |
|
566 dbg = _dwarf_get_debug(); |
|
567 if (dbg == NULL) { |
|
568 DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); |
|
569 } |
|
570 dbg->de_errhand = errhand; |
|
571 dbg->de_errarg = errarg; |
|
572 dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE; |
|
573 dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM; |
|
574 |
|
575 |
|
576 if (fstat(fd, &fstat_buf) != 0) { |
|
577 DWARF_DBG_ERROR(dbg, DW_DLE_FSTAT_ERROR, DW_DLV_ERROR); |
|
578 } |
|
579 if (!S_ISREG(fstat_buf.st_mode)) { |
|
580 DWARF_DBG_ERROR(dbg, DW_DLE_FSTAT_MODE_ERROR, DW_DLV_ERROR); |
|
581 } |
|
582 |
|
583 if (access != DW_DLC_READ) { |
|
584 DWARF_DBG_ERROR(dbg, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR); |
|
585 } |
|
586 dbg->de_access = access; |
|
587 |
|
588 #ifdef __SGI_FAST_LIBELF |
|
589 elf = elf_sgi_new(); |
|
590 if (elf == NULL) { |
|
591 DWARF_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_ERROR); |
|
592 } |
|
593 |
|
594 sres = elf_sgi_begin_fd(elf, fd, 0); |
|
595 if (sres != ELF_SGI_ERROR_OK) { |
|
596 elf_sgi_free(elf); |
|
597 DWARF_DBG_ERROR(dbg, |
|
598 _dwarf_error_code_from_elf_sgi_error_code(sres), |
|
599 DW_DLV_ERROR); |
|
600 } |
|
601 #else /* ! __SGI_FAST_LIBELF */ |
|
602 elf_version(EV_CURRENT); |
|
603 /* changed to mmap request per bug 281217. 6/95 */ |
|
604 #ifdef HAVE_ELF_C_READ_MMAP |
|
605 /* ELF_C_READ_MMAP is an SGI IRIX specific enum value from IRIX |
|
606 libelf.h meaning read but use mmap */ |
|
607 what_kind_of_elf_read = ELF_C_READ_MMAP; |
|
608 #else /* !HAVE_ELF_C_READ_MMAP */ |
|
609 /* ELF_C_READ is a portable value */ |
|
610 what_kind_of_elf_read = ELF_C_READ; |
|
611 #endif /* HAVE_ELF_C_READ_MMAP */ |
|
612 |
|
613 if ((elf = elf_begin(fd, what_kind_of_elf_read, 0)) == NULL) { |
|
614 DWARF_DBG_ERROR(dbg, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR); |
|
615 } |
|
616 #endif /* !defined(__SGI_FAST_LIBELF) */ |
|
617 |
|
618 dbg->de_elf_must_close = 1; |
|
619 if ((res = _dwarf_setup(dbg, elf, error)) != DW_DLV_OK) { |
|
620 #ifdef __SGI_FAST_LIBELF |
|
621 elf_sgi_free(elf); |
|
622 #else |
|
623 elf_end(elf); |
|
624 #endif |
|
625 free(dbg); |
|
626 return (res); |
|
627 } |
|
628 |
|
629 /* call cannot fail: no malloc or free involved */ |
|
630 _dwarf_setup_debug(dbg); |
|
631 |
|
632 *ret_dbg = dbg; |
|
633 return (DW_DLV_OK); |
|
634 } |
|
635 |
|
636 |
|
637 /* |
|
638 The alternate dwarf setup call for consumers |
|
639 */ |
|
640 int |
|
641 dwarf_elf_init(dwarf_elf_handle elf_file_pointer, |
|
642 Dwarf_Unsigned access, |
|
643 Dwarf_Handler errhand, |
|
644 Dwarf_Ptr errarg, |
|
645 Dwarf_Debug * ret_dbg, Dwarf_Error * error) |
|
646 { |
|
647 Dwarf_Debug dbg; |
|
648 int res; |
|
649 |
|
650 dbg = _dwarf_get_debug(); |
|
651 if (dbg == NULL) { |
|
652 DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); |
|
653 } |
|
654 dbg->de_errhand = errhand; |
|
655 dbg->de_errarg = errarg; |
|
656 dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE; |
|
657 dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM; |
|
658 |
|
659 if (access != DW_DLC_READ) { |
|
660 DWARF_DBG_ERROR(dbg, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR); |
|
661 } |
|
662 dbg->de_access = access; |
|
663 |
|
664 dbg->de_elf_must_close = 0; |
|
665 if ((res = _dwarf_setup(dbg, elf_file_pointer, error)) != DW_DLV_OK) { |
|
666 free(dbg); |
|
667 return (res); |
|
668 } |
|
669 |
|
670 /* this call cannot fail: allocates nothing, releases nothing */ |
|
671 _dwarf_setup_debug(dbg); |
|
672 |
|
673 *ret_dbg = dbg; |
|
674 return (DW_DLV_OK); |
|
675 } |
|
676 |
|
677 |
|
678 /* |
|
679 Frees all memory that was not previously freed |
|
680 by dwarf_dealloc. |
|
681 Aside from certain categories. |
|
682 */ |
|
683 int |
|
684 dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error) |
|
685 { |
|
686 int res = DW_DLV_OK; |
|
687 |
|
688 if (dbg->de_elf_must_close) { |
|
689 /* Must do this *before* _dwarf_free_all_of_one_debug() as that |
|
690 zeroes out dbg contents */ |
|
691 #ifdef __SGI_FAST_LIBELF |
|
692 elf_sgi_free(dbg->de_elf); |
|
693 #else |
|
694 elf_end(dbg->de_elf); |
|
695 #endif |
|
696 } |
|
697 |
|
698 res = _dwarf_free_all_of_one_debug(dbg); |
|
699 if (res == DW_DLV_ERROR) { |
|
700 DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR); |
|
701 } |
|
702 dwarf_malloc_check_complete("After Final free"); |
|
703 |
|
704 return res; |
|
705 |
|
706 |
|
707 } |
|
708 |
|
709 |
|
710 /* |
|
711 This function returns the Elf * pointer |
|
712 associated with a Dwarf_Debug. |
|
713 */ |
|
714 int |
|
715 dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf, |
|
716 Dwarf_Error * error) |
|
717 { |
|
718 if (dbg == NULL) { |
|
719 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); |
|
720 return (DW_DLV_ERROR); |
|
721 } |
|
722 |
|
723 *elf = dbg->de_elf; |
|
724 return (DW_DLV_OK); |
|
725 } |
|
726 |
|
727 |
|
728 /* |
|
729 Load the ELF section with the specified index and set the |
|
730 pointer pointed to by section_data to the memory where it |
|
731 was loaded. |
|
732 */ |
|
733 int |
|
734 _dwarf_load_section(Dwarf_Debug dbg, |
|
735 Dwarf_Half section_index, |
|
736 Dwarf_Small ** section_data, Dwarf_Error * error) |
|
737 { |
|
738 if (section_index == 0) { |
|
739 return DW_DLV_NO_ENTRY; |
|
740 } |
|
741 |
|
742 /* check to see if the section is already loaded */ |
|
743 if (*section_data != NULL) { |
|
744 return DW_DLV_OK; |
|
745 } |
|
746 |
|
747 { |
|
748 #ifdef __SGI_FAST_LIBELF |
|
749 enum elf_sgi_error_type sres; |
|
750 |
|
751 sres = elf_sgi_section(dbg->de_elf, |
|
752 section_index, (void **) section_data); |
|
753 if (sres != ELF_SGI_ERROR_OK) { |
|
754 DWARF_DBG_ERROR(dbg, |
|
755 _dwarf_error_code_from_elf_sgi_error_code |
|
756 (sres), DW_DLV_ERROR); |
|
757 } |
|
758 #else |
|
759 Elf_Scn *scn; |
|
760 Elf_Data *data; |
|
761 |
|
762 scn = elf_getscn(dbg->de_elf, section_index); |
|
763 if (scn == NULL) { |
|
764 _dwarf_error(dbg, error, DW_DLE_MDE); |
|
765 return DW_DLV_ERROR; |
|
766 } |
|
767 |
|
768 /* |
|
769 When using libelf as a producer, section data may be stored |
|
770 in multiple buffers. In libdwarf however, we only use libelf |
|
771 as a consumer (there is a dwarf producer API, but it doesn't |
|
772 use libelf). Because of this, this single call to elf_getdata |
|
773 will retrieve the entire section in a single contiguous |
|
774 buffer. */ |
|
775 data = elf_getdata(scn, NULL); |
|
776 if (data == NULL) { |
|
777 _dwarf_error(dbg, error, DW_DLE_MDE); |
|
778 return DW_DLV_ERROR; |
|
779 } |
|
780 |
|
781 *section_data = data->d_buf; |
|
782 #endif /* !defined(__SGI_FAST_LIBELF) */ |
|
783 } |
|
784 |
|
785 return DW_DLV_OK; |
|
786 } |
|
787 |
|
788 /* This is a hack so clients can verify offsets. |
|
789 Added April 2005 so that debugger can detect broken offsets |
|
790 (which happened in an IRIX -64 executable larger than 2GB |
|
791 using MIPSpro 7.3.1.3 compilers. A couple .debug_pubnames |
|
792 offsets were wrong.). |
|
793 */ |
|
794 int |
|
795 dwarf_get_section_max_offsets(Dwarf_Debug dbg, |
|
796 Dwarf_Unsigned * debug_info_size, |
|
797 Dwarf_Unsigned * debug_abbrev_size, |
|
798 Dwarf_Unsigned * debug_line_size, |
|
799 Dwarf_Unsigned * debug_loc_size, |
|
800 Dwarf_Unsigned * debug_aranges_size, |
|
801 Dwarf_Unsigned * debug_macinfo_size, |
|
802 Dwarf_Unsigned * debug_pubnames_size, |
|
803 Dwarf_Unsigned * debug_str_size, |
|
804 Dwarf_Unsigned * debug_frame_size, |
|
805 Dwarf_Unsigned * debug_ranges_size, |
|
806 Dwarf_Unsigned * debug_typenames_size) |
|
807 { |
|
808 *debug_info_size = dbg->de_debug_info_size; |
|
809 *debug_abbrev_size = dbg->de_debug_abbrev_size; |
|
810 *debug_line_size = dbg->de_debug_line_size; |
|
811 *debug_loc_size = dbg->de_debug_loc_size; |
|
812 *debug_aranges_size = dbg->de_debug_aranges_size; |
|
813 *debug_macinfo_size = dbg->de_debug_macinfo_size; |
|
814 *debug_pubnames_size = dbg->de_debug_pubnames_size; |
|
815 *debug_str_size = dbg->de_debug_str_size; |
|
816 *debug_frame_size = dbg->de_debug_frame_size; |
|
817 *debug_ranges_size = 0; /* Not yet supported. */ |
|
818 *debug_typenames_size = dbg->de_debug_typenames_size; |
|
819 |
|
820 |
|
821 return DW_DLV_OK; |
|
822 } |