1 /*
2 Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved.
3 Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
4 Portions Copyright 2008-2010 Arxan Technologies, Inc. All Rights Reserved.
5 Portions Copyright 2009-2019 David Anderson. All rights reserved.
6 Portions Copyright 2009-2010 Novell Inc. All rights reserved.
7 Portions Copyright 2012 SN Systems Ltd. All rights reserved.
8
9 This program is free software; you can redistribute it
10 and/or modify it under the terms of version 2.1 of the
11 GNU Lesser General Public License as published by the Free
12 Software Foundation.
13
14 This program is distributed in the hope that it would be
15 useful, but WITHOUT ANY WARRANTY; without even the implied
16 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
17 PURPOSE.
18
19 Further, this software is distributed without any warranty
20 that it is free of the rightful claim of any third person
21 regarding infringement or the like. Any license provided
22 herein, whether implied or otherwise, applies only to this
23 software file. Patent licenses, if any, provided herein
24 do not apply to combinations of this program with other
25 software, or any other product whatsoever.
26
27 You should have received a copy of the GNU Lesser General
28 Public License along with this program; if not, write the
29 Free Software Foundation, Inc., 51 Franklin Street - Fifth
30 Floor, Boston MA 02110-1301, USA.
31
32 */
33
34 /* This file is ONLY used for libelf and with libelf
35 For */
36
37 #include "config.h"
38 #ifdef DWARF_WITH_LIBELF
39 #include "dwarf_incl.h"
40 #include "dwarf_error.h"
41 #include "dwarf_elf_access.h"
42 #include "dwarf_elf_rel_detector.h"
43
44 /* Include the ELF definitions depending on system headers if any. */
45 #include "dwarf_elf_defines.h"
46
47 #include <stdio.h>
48 #include <sys/stat.h>
49 #include <sys/types.h>
50 #ifdef HAVE_UNISTD_H
51 #include <unistd.h> /* for close */
52 #endif /* HAVE_UNISTD_H */
53 #include <string.h>
54 #ifdef HAVE_STDLIB_H
55 #include <stdlib.h>
56 #endif /* HAVE_STDLIB_H */
57 #ifdef HAVE_MALLOC_H
58 /* Useful include for some Windows compilers. */
59 #include <malloc.h>
60 #endif /* HAVE_MALLOC_H */
61
62 #define FALSE 0
63 #define TRUE 1
64
65 #ifdef HAVE_ELF64_GETEHDR
66 extern Elf64_Ehdr *elf64_getehdr(Elf *);
67 #endif
68 #ifdef HAVE_ELF64_GETSHDR
69 extern Elf64_Shdr *elf64_getshdr(Elf_Scn *);
70 #endif
71
72 #ifdef WORDS_BIGENDIAN
73 #define READ_UNALIGNED_SAFE(dbg,dest, source, length) \
74 do { \
75 Dwarf_Unsigned _ltmp = 0; \
76 dbg->de_copy_word( (((char *)(&_ltmp)) + \
77 sizeof(_ltmp) - length),source, length); \
78 dest = _ltmp; \
79 } while (0)
80
81 #define WRITE_UNALIGNED_LOCAL(dbg,dest,source, srclength,len_out) \
82 { \
83 dbg->de_copy_word(dest, \
84 ((char *)source) +srclength-len_out, \
85 len_out) ; \
86 }
87 #else /* LITTLE ENDIAN */
88 #define READ_UNALIGNED_SAFE(dbg,dest, source, srclength) \
89 do { \
90 Dwarf_Unsigned _ltmp = 0; \
91 dbg->de_copy_word( (char *)(&_ltmp), \
92 source, srclength) ; \
93 dest = _ltmp; \
94 } while (0)
95
96 #define WRITE_UNALIGNED_LOCAL(dbg,dest,source, srclength,len_out) \
97 { \
98 dbg->de_copy_word( (dest) , \
99 ((char *)source) , \
100 len_out) ; \
101 }
102 #endif /* *-ENDIAN */
103
104
105
106 /* ident[0] == 'E' for elf when using libelf. ident[1] = 1 */
107 typedef struct {
108 char ident[8];
109 const char * path;
110 int is_64bit;
111 Dwarf_Small length_size;
112 Dwarf_Small pointer_size;
113 Dwarf_Unsigned section_count;
114 Dwarf_Endianness endianness;
115 Dwarf_Small machine;
116 char libdwarf_owns_elf;
117 dwarf_elf_handle elf;
118
119 Elf32_Ehdr *ehdr32;
120 #ifdef HAVE_ELF64_GETEHDR
121 Elf64_Ehdr *ehdr64;
122 #endif
123 /* Elf symtab and its strtab. Initialized at first
124 call to do relocations, the actual data is in the Dwarf_Debug
125 struct, not allocated locally here. */
126 struct Dwarf_Section_s *symtab;
127 struct Dwarf_Section_s *strtab;
128
129 } dwarf_elf_object_access_internals_t;
130
131 /* Using this for rel and rela.
132 For Rel, r_addend is left zero and not used.
133 */
134 struct Dwarf_Elf_Rela {
135 Dwarf_Unsigned r_offset;
136 /*Dwarf_Unsigned r_info; */
137 Dwarf_Unsigned r_type;
138 Dwarf_Unsigned r_symidx;
139 Dwarf_Unsigned r_addend;
140 /* if is_rela is non-zero r_addend is meaningless */
141 char r_is_rela;
142 };
143
144
145 static int dwarf_elf_object_access_load_section(void* obj_in,
146 Dwarf_Half section_index,
147 Dwarf_Small** section_data,
148 int* error);
149
150 /* dwarf_elf_object_access_internals_init()
151 On error, set *error with libdwarf error code.
152 */
153 static int
dwarf_elf_object_access_internals_init(void * obj_in,dwarf_elf_handle elf,int * error)154 dwarf_elf_object_access_internals_init(void* obj_in,
155 dwarf_elf_handle elf,
156 int* error)
157 {
158 dwarf_elf_object_access_internals_t*obj =
159 (dwarf_elf_object_access_internals_t*)obj_in;
160 char *ehdr_ident = 0;
161 Dwarf_Half machine = 0;
162 obj->elf = elf;
163
164 if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {
165 *error = DW_DLE_ELF_GETIDENT_ERROR;
166 return DW_DLV_ERROR;
167 }
168
169 obj->is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64);
170
171
172 if (ehdr_ident[EI_DATA] == ELFDATA2LSB){
173 obj->endianness = DW_OBJECT_LSB;
174 } else if (ehdr_ident[EI_DATA] == ELFDATA2MSB){
175 obj->endianness = DW_OBJECT_MSB;
176 }
177
178 if (obj->is_64bit) {
179 #ifdef HAVE_ELF64_GETEHDR
180 obj->ehdr64 = elf64_getehdr(elf);
181 if (obj->ehdr64 == NULL) {
182 *error = DW_DLE_ELF_GETEHDR_ERROR;
183 return DW_DLV_ERROR;
184 }
185 obj->section_count = obj->ehdr64->e_shnum;
186 machine = obj->ehdr64->e_machine;
187 obj->machine = machine;
188 #else
189 *error = DW_DLE_NO_ELF64_SUPPORT;
190 return DW_DLV_ERROR;
191 #endif
192 } else {
193 obj->ehdr32 = elf32_getehdr(elf);
194 if (obj->ehdr32 == NULL) {
195 *error = DW_DLE_ELF_GETEHDR_ERROR;
196 return DW_DLV_ERROR;
197 }
198 obj->section_count = obj->ehdr32->e_shnum;
199 machine = obj->ehdr32->e_machine;
200 obj->machine = machine;
201 }
202
203 /* The following length_size is Not Too Significant. Only used
204 one calculation, and an approximate one at that. */
205 obj->length_size = obj->is_64bit ? 8 : 4;
206 obj->pointer_size = obj->is_64bit ? 8 : 4;
207 obj->ident[0] = 'E';
208 obj->ident[1] = 1;
209
210 #ifdef _WIN32
211 if (obj->is_64bit && machine == EM_PPC64) {
212 /* The SNC compiler generates the EM_PPC64 machine type for the
213 PS3 platform, but is a 32 bits pointer size in user mode. */
214 obj->pointer_size = 4;
215 }
216 #endif /* _WIN32 */
217
218 if (obj->is_64bit && machine != EM_MIPS) {
219 /* MIPS/IRIX makes pointer size and length size 8 for -64.
220 Other platforms make length 4 always. */
221 /* 4 here supports 32bit-offset dwarf2, as emitted by cygnus
222 tools, and the dwarfv2.1 64bit extension setting.
223 This is not the same as the size-of-an-offset, which
224 is 4 in 32bit dwarf and 8 in 64bit dwarf. */
225 obj->length_size = 4;
226 }
227 return DW_DLV_OK;
228 }
229
230 /* dwarf_elf_object_access_get_byte_order */
231 static
232 Dwarf_Endianness
dwarf_elf_object_access_get_byte_order(void * obj_in)233 dwarf_elf_object_access_get_byte_order(void* obj_in)
234 {
235 dwarf_elf_object_access_internals_t*obj =
236 (dwarf_elf_object_access_internals_t*)obj_in;
237 return obj->endianness;
238 }
239
240 /* dwarf_elf_object_access_get_section_count() */
241 static
242 Dwarf_Unsigned
dwarf_elf_object_access_get_section_count(void * obj_in)243 dwarf_elf_object_access_get_section_count(void * obj_in)
244 {
245 dwarf_elf_object_access_internals_t*obj =
246 (dwarf_elf_object_access_internals_t*)obj_in;
247 return obj->section_count;
248 }
249
250
251 static int
_dwarf_get_elf_flags_func(void * obj_in,Dwarf_Half section_index,Dwarf_Unsigned * flags_out,Dwarf_Unsigned * addralign_out,int * error)252 _dwarf_get_elf_flags_func(
253 void* obj_in,
254 Dwarf_Half section_index,
255 Dwarf_Unsigned *flags_out,
256 Dwarf_Unsigned *addralign_out,
257 int *error)
258 {
259 dwarf_elf_object_access_internals_t*obj =
260 (dwarf_elf_object_access_internals_t*)obj_in;
261
262 Elf32_Shdr *shdr32 = 0;
263
264 #ifdef HAVE_ELF64_GETSHDR
265 Elf64_Shdr *shdr64 = 0;
266 #endif
267 Elf_Scn *scn = 0;
268
269
270 scn = elf_getscn(obj->elf, section_index);
271 if (scn == NULL) {
272 *error = DW_DLE_MDE;
273 return DW_DLV_ERROR;
274 }
275 if (obj->is_64bit) {
276 #ifdef HAVE_ELF64_GETSHDR
277 shdr64 = elf64_getshdr(scn);
278 if (shdr64 == NULL) {
279 *error = DW_DLE_ELF_GETSHDR_ERROR;
280 return DW_DLV_ERROR;
281 }
282
283 /* Get also section 'sh_type' and sh_info' fields, so the caller
284 can use it for additional tasks that require that info. */
285 *flags_out = shdr64->sh_flags;
286 *addralign_out = shdr64->sh_addralign;
287 return DW_DLV_OK;
288 #else
289 *error = DW_DLE_MISSING_ELF64_SUPPORT;
290 return DW_DLV_ERROR;
291 #endif /* HAVE_ELF64_GETSHDR */
292 }
293 if ((shdr32 = elf32_getshdr(scn)) == NULL) {
294 *error = DW_DLE_ELF_GETSHDR_ERROR;
295 return DW_DLV_ERROR;
296 }
297
298 /* Get also the section type, so the caller can use it for
299 additional tasks that require to know the section type. */
300 *flags_out = shdr32->sh_flags;
301 *addralign_out = shdr32->sh_addralign;
302 return DW_DLV_OK;
303 }
304
305
306 /* dwarf_elf_object_access_get_section()
307
308 If writing a function vaguely like this for a non-elf object,
309 be sure that when section-index is passed in as zero that
310 you set the fields in *ret_scn_doas to reflect an empty section
311 with an empty string as the section name. Adjust your
312 section indexes of your non-elf-reading-code
313 for all the necessary functions in Dwarf_Obj_Access_Methods_s
314 accordingly.
315
316 Should have gotten sh_flags, sh_addralign too.
317 But Dwarf_Obj_Access_Section is publically defined so changing
318 it is quite painful for everyone.
319 */
320 static
321 int
dwarf_elf_object_access_get_section_info(void * obj_in,Dwarf_Half section_index,Dwarf_Obj_Access_Section * ret_scn_doas,int * error)322 dwarf_elf_object_access_get_section_info(
323 void* obj_in,
324 Dwarf_Half section_index,
325 Dwarf_Obj_Access_Section* ret_scn_doas,
326 int* error)
327 {
328 dwarf_elf_object_access_internals_t*obj =
329 (dwarf_elf_object_access_internals_t*)obj_in;
330
331 Elf32_Shdr *shdr32 = 0;
332
333 #ifdef HAVE_ELF64_GETSHDR
334 Elf64_Shdr *shdr64 = 0;
335 #endif
336 Elf_Scn *scn = 0;
337
338
339 scn = elf_getscn(obj->elf, section_index);
340 if (scn == NULL) {
341 *error = DW_DLE_MDE;
342 return DW_DLV_ERROR;
343 }
344 if (obj->is_64bit) {
345 #ifdef HAVE_ELF64_GETSHDR
346 shdr64 = elf64_getshdr(scn);
347 if (shdr64 == NULL) {
348 *error = DW_DLE_ELF_GETSHDR_ERROR;
349 return DW_DLV_ERROR;
350 }
351
352 /* Get also section 'sh_type' and sh_info' fields, so the caller
353 can use it for additional tasks that require that info. */
354 ret_scn_doas->type = shdr64->sh_type;
355 ret_scn_doas->size = shdr64->sh_size;
356 ret_scn_doas->addr = shdr64->sh_addr;
357 ret_scn_doas->link = shdr64->sh_link;
358 ret_scn_doas->info = shdr64->sh_info;
359 ret_scn_doas->entrysize = shdr64->sh_entsize;
360 ret_scn_doas->name = elf_strptr(obj->elf, obj->ehdr64->e_shstrndx,
361 shdr64->sh_name);
362 if (ret_scn_doas->name == NULL) {
363 *error = DW_DLE_ELF_STRPTR_ERROR;
364 return DW_DLV_ERROR;
365 }
366 return DW_DLV_OK;
367 #else
368 *error = DW_DLE_MISSING_ELF64_SUPPORT;
369 return DW_DLV_ERROR;
370 #endif /* HAVE_ELF64_GETSHDR */
371 }
372 if ((shdr32 = elf32_getshdr(scn)) == NULL) {
373 *error = DW_DLE_ELF_GETSHDR_ERROR;
374 return DW_DLV_ERROR;
375 }
376
377 /* Get also the section type, so the caller can use it for
378 additional tasks that require to know the section type. */
379 ret_scn_doas->type = shdr32->sh_type;
380 ret_scn_doas->size = shdr32->sh_size;
381 ret_scn_doas->addr = shdr32->sh_addr;
382 ret_scn_doas->link = shdr32->sh_link;
383 ret_scn_doas->info = shdr32->sh_info;
384 ret_scn_doas->entrysize = shdr32->sh_entsize;
385 ret_scn_doas->name = elf_strptr(obj->elf, obj->ehdr32->e_shstrndx,
386 shdr32->sh_name);
387 if (ret_scn_doas->name == NULL) {
388 *error = DW_DLE_ELF_STRPTR_ERROR;
389 return DW_DLV_ERROR;
390 }
391 return DW_DLV_OK;
392 }
393
394 /* dwarf_elf_object_access_get_length_size */
395 static
396 Dwarf_Small
dwarf_elf_object_access_get_length_size(void * obj_in)397 dwarf_elf_object_access_get_length_size(void* obj_in)
398 {
399 dwarf_elf_object_access_internals_t*obj =
400 (dwarf_elf_object_access_internals_t*)obj_in;
401 return obj->length_size;
402 }
403
404 /* dwarf_elf_object_access_get_pointer_size */
405 static
406 Dwarf_Small
dwarf_elf_object_access_get_pointer_size(void * obj_in)407 dwarf_elf_object_access_get_pointer_size(void* obj_in)
408 {
409 dwarf_elf_object_access_internals_t*obj =
410 (dwarf_elf_object_access_internals_t*)obj_in;
411 return obj->pointer_size;
412 }
413
414 #define MATCH_REL_SEC(i_,s_,r_) \
415 if (i_ == s_.dss_index) { \
416 *r_ = &s_; \
417 return DW_DLV_OK; \
418 }
419
420 static int
find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index,struct Dwarf_Section_s ** relocatablesec,int * error)421 find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index,
422 struct Dwarf_Section_s **relocatablesec, int *error)
423 {
424 MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec);
425 MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec);
426 MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec);
427 MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec);
428 MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec);
429 MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec);
430 MATCH_REL_SEC(section_index,dbg->de_debug_pubnames,relocatablesec);
431 MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec);
432 MATCH_REL_SEC(section_index,dbg->de_debug_frame,relocatablesec);
433 MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu,relocatablesec);
434 MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes,relocatablesec);
435 MATCH_REL_SEC(section_index,dbg->de_debug_funcnames,relocatablesec);
436 MATCH_REL_SEC(section_index,dbg->de_debug_typenames,relocatablesec);
437 MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec);
438 MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec);
439 MATCH_REL_SEC(section_index,dbg->de_debug_types,relocatablesec);
440 MATCH_REL_SEC(section_index,dbg->de_debug_macro,relocatablesec);
441 MATCH_REL_SEC(section_index,dbg->de_debug_rnglists,relocatablesec);
442 MATCH_REL_SEC(section_index,dbg->de_debug_loclists,relocatablesec);
443 MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec);
444 MATCH_REL_SEC(section_index,dbg->de_debug_sup,relocatablesec);
445 MATCH_REL_SEC(section_index,dbg->de_debug_str_offsets,relocatablesec);
446 MATCH_REL_SEC(section_index,dbg->de_debug_addr,relocatablesec);
447 /* dbg-> de_debug_tu_index,reloctablesec); */
448 /* dbg-> de_debug_cu_index,reloctablesec); */
449 /* dbg-> de_debug_gdbindex,reloctablesec); */
450 /* dbg-> de_debug_str,syms); */
451 /* de_elf_symtab,syms); */
452 /* de_elf_strtab,syms); */
453 *error = DW_DLE_RELOC_SECTION_MISMATCH;
454 return DW_DLV_ERROR;
455
456 }
457 #undef MATCH_REL_SEC
458
459 static void
get_rela_elf32(Dwarf_Small * data,unsigned int i,UNUSEDARG int endianness,UNUSEDARG int machine,struct Dwarf_Elf_Rela * relap)460 get_rela_elf32(Dwarf_Small *data, unsigned int i,
461 UNUSEDARG int endianness,
462 UNUSEDARG int machine,
463 struct Dwarf_Elf_Rela *relap)
464 {
465 Elf32_Rela *relp = 0;
466
467 relp = (Elf32_Rela*)(data + (i * sizeof(Elf32_Rela)));
468 relap->r_offset = relp->r_offset;
469 /* relap->r_info = relp->r_info; */
470 relap->r_type = ELF32_R_TYPE(relp->r_info);
471 relap->r_symidx = ELF32_R_SYM(relp->r_info);
472 relap->r_is_rela = TRUE;
473 relap->r_addend = relp->r_addend;
474 }
475 static void
get_rel_elf32(Dwarf_Small * data,unsigned int i,UNUSEDARG int endianness,UNUSEDARG int machine,struct Dwarf_Elf_Rela * relap)476 get_rel_elf32(Dwarf_Small *data, unsigned int i,
477 UNUSEDARG int endianness,
478 UNUSEDARG int machine,
479 struct Dwarf_Elf_Rela *relap)
480 {
481 Elf32_Rel *relp = 0;
482
483 relp = (Elf32_Rel*)(data + (i * sizeof(Elf32_Rel)));
484 relap->r_offset = relp->r_offset;
485 /* relap->r_info = relp->r_info; */
486 relap->r_type = ELF32_R_TYPE(relp->r_info);
487 relap->r_symidx = ELF32_R_SYM(relp->r_info);
488 relap->r_is_rela = FALSE;
489 relap->r_addend = 0;
490 }
491
492
493 static void
get_rela_elf64(Dwarf_Small * data,unsigned int i,int endianness,int machine,struct Dwarf_Elf_Rela * relap)494 get_rela_elf64(Dwarf_Small *data, unsigned int i,
495 int endianness,
496 int machine,
497 struct Dwarf_Elf_Rela *relap)
498 {
499 #ifdef HAVE_ELF64_RELA
500 Elf64_Rela * relp = 0;
501 relp = (Elf64_Rela*)(data + (i * sizeof(Elf64_Rela)));
502 relap->r_offset = relp->r_offset;
503 /* relap->r_info = relp->r_info; */
504 #define ELF64MIPS_REL_SYM(i) ((i) & 0xffffffff)
505 #define ELF64MIPS_REL_TYPE(i) ((i >> 56) &0xff)
506 if (machine == EM_MIPS && endianness == DW_OBJECT_LSB ){
507 /* This is really wierd. Treat this very specially.
508 The Elf64 LE MIPS object used for
509 testing (that has rela) wants the
510 values as sym ssym type3 type2 type, treating
511 each value as independent value. But libelf xlate
512 treats it as something else so we fudge here.
513 It is unclear
514 how to precisely characterize where these relocations
515 were used.
516 SGI MIPS on IRIX never used .rela relocations.
517 The BE 64bit elf MIPS test object with rela uses traditional
518 elf relocation layouts, not this special case. */
519 /* We ignore the special TYPE2 and TYPE3, they should be
520 value R_MIPS_NONE in rela. */
521 relap->r_type = ELF64MIPS_REL_TYPE(relp->r_info);
522 relap->r_symidx = ELF64MIPS_REL_SYM(relp->r_info);
523 #undef MIPS64SYM
524 #undef MIPS64TYPE
525 } else
526 {
527 relap->r_type = ELF64_R_TYPE(relp->r_info);
528 relap->r_symidx = ELF64_R_SYM(relp->r_info);
529 }
530 relap->r_addend = relp->r_addend;
531 relap->r_is_rela = TRUE;
532 #endif
533 }
534
535 static void
get_rel_elf64(Dwarf_Small * data,unsigned int i,int endianness,int machine,struct Dwarf_Elf_Rela * relap)536 get_rel_elf64(Dwarf_Small *data, unsigned int i,
537 int endianness,
538 int machine,
539 struct Dwarf_Elf_Rela *relap)
540 {
541 #ifdef HAVE_ELF64_RELA
542 Elf64_Rel * relp = 0;
543 relp = (Elf64_Rel*)(data + (i * sizeof(Elf64_Rel)));
544 relap->r_offset = relp->r_offset;
545 /* relap->r_info = relp->r_info; */
546 #define ELF64MIPS_REL_SYM(i) ((i) & 0xffffffff)
547 #define ELF64MIPS_REL_TYPE(i) ((i >> 56) &0xff)
548 if (machine == EM_MIPS && endianness == DW_OBJECT_LSB ){
549 /* This is really wierd. Treat this very specially.
550 The Elf64 LE MIPS object used for
551 testing (that has rela) wants the
552 values as sym ssym type3 type2 type, treating
553 each value as independent value. But libelf xlate
554 treats it as something else so we fudge here.
555 It is unclear
556 how to precisely characterize where these relocations
557 were used.
558 SGI MIPS on IRIX never used .rela relocations.
559 The BE 64bit elf MIPS test object with rela uses traditional
560 elf relocation layouts, not this special case. */
561 /* We ignore the special TYPE2 and TYPE3, they should be
562 value R_MIPS_NONE in rela. */
563 relap->r_type = ELF64MIPS_REL_TYPE(relp->r_info);
564 relap->r_symidx = ELF64MIPS_REL_SYM(relp->r_info);
565 #undef MIPS64SYM
566 #undef MIPS64TYPE
567 } else
568 {
569 relap->r_type = ELF64_R_TYPE(relp->r_info);
570 relap->r_symidx = ELF64_R_SYM(relp->r_info);
571 }
572 relap->r_addend = 0;
573 relap->r_is_rela = FALSE;
574 #endif
575 }
576
577
578 static void
get_relocations_array(Dwarf_Bool is_64bit,int endianness,int machine,int is_rela,Dwarf_Small * data,unsigned int num_relocations,struct Dwarf_Elf_Rela * relap)579 get_relocations_array(Dwarf_Bool is_64bit,
580 int endianness,
581 int machine,
582 int is_rela,
583 Dwarf_Small *data,
584 unsigned int num_relocations,
585 struct Dwarf_Elf_Rela *relap)
586 {
587 unsigned int i = 0;
588 void (*get_relocations)(Dwarf_Small *data, unsigned int i,
589 int endianness,
590 int machine,
591 struct Dwarf_Elf_Rela *relap);
592
593 /* Handle 32/64 bit issue */
594 if (is_64bit) {
595 if ( is_rela) {
596 get_relocations = get_rela_elf64;
597 } else {
598 get_relocations = get_rel_elf64;
599 }
600 } else {
601 if ( is_rela) {
602 get_relocations = get_rela_elf32;
603 } else {
604 get_relocations = get_rel_elf32;
605 }
606 }
607
608 for (i=0; i < num_relocations; i++) {
609 get_relocations(data, i,endianness,machine,
610 &(relap[i]));
611 }
612
613 }
614
615 static int
get_relocation_entries(Dwarf_Bool is_64bit,int endianness,int machine,Dwarf_Small * relocation_section,Dwarf_Unsigned relocation_section_size,Dwarf_Unsigned relocation_section_entrysize,struct Dwarf_Elf_Rela ** relas,unsigned int * nrelas,int is_rela,int * error)616 get_relocation_entries(Dwarf_Bool is_64bit,
617 int endianness,
618 int machine,
619 Dwarf_Small *relocation_section,
620 Dwarf_Unsigned relocation_section_size,
621 Dwarf_Unsigned relocation_section_entrysize,
622 struct Dwarf_Elf_Rela **relas,
623 unsigned int *nrelas,
624 int is_rela,
625 int *error)
626 {
627 unsigned int relocation_size = 0;
628
629 if (is_64bit) {
630 #ifdef HAVE_ELF64_RELA
631 relocation_size = is_rela?sizeof(Elf64_Rela):sizeof(Elf64_Rel);
632 #else
633 *error = DW_DLE_MISSING_ELF64_SUPPORT;
634 return DW_DLV_ERROR;
635 #endif
636 } else {
637 relocation_size = is_rela?sizeof(Elf32_Rela):sizeof(Elf32_Rel);
638 }
639 if (relocation_size != relocation_section_entrysize) {
640 /* Means our struct definition does not match the
641 real object. */
642
643 *error = DW_DLE_RELOC_SECTION_LENGTH_ODD;
644 return DW_DLV_ERROR;
645 }
646
647 if (relocation_section == NULL) {
648 *error = DW_DLE_RELOC_SECTION_PTR_NULL;
649 return(DW_DLV_ERROR);
650 }
651
652 if ((relocation_section_size != 0)) {
653 size_t bytescount = 0;
654 if (relocation_section_size%relocation_size) {
655 *error = DW_DLE_RELOC_SECTION_LENGTH_ODD;
656 return DW_DLV_ERROR;
657 }
658 *nrelas = relocation_section_size/relocation_size;
659 bytescount = (*nrelas) * sizeof(struct Dwarf_Elf_Rela);
660 *relas = malloc(bytescount);
661 if (!*relas) {
662 *error = DW_DLE_MAF;
663 return(DW_DLV_ERROR);
664 }
665 memset(*relas,0,bytescount);
666 get_relocations_array(is_64bit,endianness,machine,
667 is_rela,
668 relocation_section,
669 *nrelas, *relas);
670 }
671 return(DW_DLV_OK);
672 }
673
674 /* Returns DW_DLV_OK if it works, else DW_DLV_ERROR.
675 The caller may decide to ignore the errors or report them. */
676 static int
update_entry(Dwarf_Debug dbg,Dwarf_Bool is_64bit,UNUSEDARG Dwarf_Endianness endianess,UNUSEDARG Dwarf_Half machine,struct Dwarf_Elf_Rela * rela,Dwarf_Small * target_section,Dwarf_Unsigned target_section_size,Dwarf_Small * symtab_section_data,Dwarf_Unsigned symtab_section_size,Dwarf_Unsigned symtab_section_entrysize,int is_rela,int * error)677 update_entry(Dwarf_Debug dbg,
678 Dwarf_Bool is_64bit,
679 UNUSEDARG Dwarf_Endianness endianess,
680 UNUSEDARG Dwarf_Half machine,
681 struct Dwarf_Elf_Rela *rela,
682 Dwarf_Small *target_section,
683 Dwarf_Unsigned target_section_size,
684 Dwarf_Small *symtab_section_data,
685 Dwarf_Unsigned symtab_section_size,
686 Dwarf_Unsigned symtab_section_entrysize,
687 int is_rela,
688 int *error)
689 {
690 unsigned int type = 0;
691 unsigned int sym_idx = 0;
692 #ifdef HAVE_ELF64_SYM
693 Elf64_Sym sym_buf;
694 Elf64_Sym *sym = 0;
695 #else
696 Elf32_Sym sym_buf;
697 Elf32_Sym *sym = 0;
698 #endif
699 Elf32_Sym *sym32 = 0;
700 Dwarf_Unsigned offset = 0;
701 Dwarf_Signed addend = 0;
702 Dwarf_Unsigned reloc_size = 0;
703 Dwarf_Unsigned symtab_entry_count = 0;
704
705 if (symtab_section_entrysize == 0) {
706 *error = DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO;
707 return DW_DLV_ERROR;
708 }
709 symtab_entry_count = symtab_section_size/symtab_section_entrysize;
710
711 /* Dwarf_Elf_Rela dereferencing */
712 offset = rela->r_offset;
713 addend = rela->r_addend;
714 type = rela->r_type;
715 sym_idx = rela->r_symidx;
716 if (sym_idx >= symtab_entry_count) {
717 *error = DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD;
718 return DW_DLV_ERROR;
719 }
720 if (offset >= target_section_size) {
721 /* If offset really big, any add will overflow.
722 So lets stop early if offset is corrupt. */
723 *error = DW_DLE_RELOC_INVALID;
724 return DW_DLV_ERROR;
725 }
726 if (is_64bit) {
727 #ifdef HAVE_ELF64_SYM
728 sym = &((Elf64_Sym*)symtab_section_data)[sym_idx];
729 #else
730 /* We cannot handle this object without 64_SYMs. */
731 *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN;
732 return DW_DLV_ERROR;
733 #endif
734 } else {
735 sym32 = &((Elf32_Sym*)symtab_section_data)[sym_idx];
736
737 /* Convert Elf32_Sym struct to Elf64_Sym struct. We point at
738 an Elf64_Sym local variable (sym_buf) to allow us to use the
739 same pointer (sym) for both 32-bit and 64-bit instances. */
740 sym = &sym_buf;
741 sym->st_name = sym32->st_name;
742 sym->st_info = sym32->st_info;
743 sym->st_other = sym32->st_other;
744 sym->st_shndx = sym32->st_shndx;
745 sym->st_value = sym32->st_value;
746 sym->st_size = sym32->st_size;
747 }
748
749 /* Determine relocation size */
750 if (_dwarf_is_32bit_abs_reloc(type, machine)) {
751 reloc_size = 4;
752 } else if (_dwarf_is_64bit_abs_reloc(type, machine)) {
753 reloc_size = 8;
754 } else {
755 *error = DW_DLE_RELOC_SECTION_RELOC_TARGET_SIZE_UNKNOWN;
756 return DW_DLV_ERROR;
757 }
758 if ( (offset + reloc_size) < offset) {
759 /* Another check for overflow. */
760 *error = DW_DLE_RELOC_INVALID;
761 return DW_DLV_ERROR;
762 }
763 if ( (offset + reloc_size) > target_section_size) {
764 *error = DW_DLE_RELOC_INVALID;
765 return DW_DLV_ERROR;
766 }
767 { /* .rel. (addend is zero) or .rela */
768 Dwarf_Small *targ = target_section+offset;
769 Dwarf_Unsigned presentval = 0;
770 Dwarf_Unsigned outval = 0;
771 /* See also: READ_UNALIGNED_SAFE in
772 dwarf_elfread.c */
773
774 if (!is_rela) {
775 READ_UNALIGNED_SAFE(dbg,presentval,
776 targ,reloc_size);
777 }
778 /* There is no addend in .rel.
779 Normally presentval is correct
780 and st_value will be zero.
781 But a few compilers have
782 presentval zero and st_value set. */
783 outval = presentval + sym->st_value + addend ;
784 WRITE_UNALIGNED_LOCAL(dbg,targ,
785 &outval,sizeof(outval),reloc_size);
786 }
787 return DW_DLV_OK;
788 }
789
790
791
792 /* Somewhat arbitrarily, we attempt to apply all the relocations we can
793 and still notify the caller of at least one error if we found
794 any errors. */
795 static int
apply_rela_entries(Dwarf_Debug dbg,Dwarf_Bool is_64bit,Dwarf_Endianness endianess,Dwarf_Half machine,Dwarf_Small * target_section,Dwarf_Unsigned target_section_size,Dwarf_Small * symtab_section,Dwarf_Unsigned symtab_section_size,Dwarf_Unsigned symtab_section_entrysize,int is_rela,struct Dwarf_Elf_Rela * relas,unsigned int nrelas,int * error)796 apply_rela_entries(Dwarf_Debug dbg,
797 Dwarf_Bool is_64bit,
798 Dwarf_Endianness endianess,
799 Dwarf_Half machine,
800 Dwarf_Small *target_section,
801 Dwarf_Unsigned target_section_size,
802 Dwarf_Small *symtab_section,
803 Dwarf_Unsigned symtab_section_size,
804 Dwarf_Unsigned symtab_section_entrysize,
805 int is_rela,
806 struct Dwarf_Elf_Rela *relas, unsigned int nrelas,
807 int *error)
808 {
809 int return_res = DW_DLV_OK;
810 if ((target_section != NULL) && (relas != NULL)) {
811 unsigned int i;
812 if (symtab_section_entrysize == 0) {
813 *error = DW_DLE_SYMTAB_SECTION_ENTRYSIZE_ZERO;
814 return DW_DLV_ERROR;
815 }
816 if (symtab_section_size%symtab_section_entrysize) {
817 *error = DW_DLE_SYMTAB_SECTION_LENGTH_ODD;
818 return DW_DLV_ERROR;
819 }
820 for (i = 0; i < nrelas; i++) {
821 int res = update_entry(dbg, is_64bit,
822 endianess,
823 machine,
824 &(relas)[i],
825 target_section,
826 target_section_size,
827 symtab_section,
828 symtab_section_size,
829 symtab_section_entrysize,
830 is_rela,
831 error);
832 if (res != DW_DLV_OK) {
833 return_res = res;
834 }
835 }
836 }
837 return return_res;
838 }
839
840
841 static int
loop_through_relocations(Dwarf_Debug dbg,dwarf_elf_object_access_internals_t * obj,struct Dwarf_Section_s * relocatablesec,int * error)842 loop_through_relocations(
843 Dwarf_Debug dbg,
844 dwarf_elf_object_access_internals_t* obj,
845 struct Dwarf_Section_s *relocatablesec,
846 int *error)
847 {
848 Dwarf_Small *target_section = 0;
849 Dwarf_Small *symtab_section = obj->symtab->dss_data;
850 Dwarf_Unsigned symtab_section_entrysize = obj->symtab->dss_entrysize;
851 Dwarf_Unsigned symtab_section_size = obj->symtab->dss_size;
852 Dwarf_Small *relocation_section = relocatablesec->dss_reloc_data;
853 Dwarf_Unsigned relocation_section_size =
854 relocatablesec->dss_reloc_size;
855 Dwarf_Unsigned relocation_section_entrysize = relocatablesec->dss_reloc_entrysize;
856 int ret = DW_DLV_ERROR;
857 struct Dwarf_Elf_Rela *relas = 0;
858 unsigned int nrelas = 0;
859 Dwarf_Small *mspace = 0;
860 int is_rela = relocatablesec->dss_is_rela;
861
862 ret = get_relocation_entries(obj->is_64bit,
863 obj->endianness,
864 obj->machine,
865 relocation_section,
866 relocation_section_size,
867 relocation_section_entrysize,
868 &relas, &nrelas, is_rela,error);
869 if (ret != DW_DLV_OK) {
870 free(relas);
871 return ret;
872 }
873
874 if(!relocatablesec->dss_data_was_malloc) {
875 /* Some systems read Elf in read-only memory via mmap or the like.
876 So the only safe thing is to copy the current data into
877 malloc space and refer to the malloc space instead of the
878 space returned by the elf library */
879 mspace = malloc(relocatablesec->dss_size);
880 if (!mspace) {
881 free(relas);
882 *error = DW_DLE_RELOC_SECTION_MALLOC_FAIL;
883 return DW_DLV_ERROR;
884 }
885 memcpy(mspace,relocatablesec->dss_data,relocatablesec->dss_size);
886 relocatablesec->dss_data = mspace;
887 relocatablesec->dss_data_was_malloc = TRUE;
888 }
889 target_section = relocatablesec->dss_data;
890 ret = apply_rela_entries(
891 dbg,
892 obj->is_64bit,
893 obj->endianness, obj->machine,
894 target_section,
895 relocatablesec->dss_size,
896 symtab_section,
897 symtab_section_size,
898 symtab_section_entrysize,
899 is_rela,
900 relas, nrelas, error);
901 free(relas);
902 return ret;
903 }
904
905 /* Find the section data in dbg and find all the relevant
906 sections. Then do relocations.
907 */
908 static int
dwarf_elf_object_relocate_a_section(void * obj_in,Dwarf_Half section_index,Dwarf_Debug dbg,int * error)909 dwarf_elf_object_relocate_a_section(void* obj_in,
910 Dwarf_Half section_index,
911 Dwarf_Debug dbg,
912 int* error)
913 {
914 int res = DW_DLV_ERROR;
915 dwarf_elf_object_access_internals_t*obj = 0;
916 struct Dwarf_Section_s * relocatablesec = 0;
917 if (section_index == 0) {
918 return DW_DLV_NO_ENTRY;
919 }
920 obj = (dwarf_elf_object_access_internals_t*)obj_in;
921
922 /* The section to relocate must already be loaded into memory. */
923 res = find_section_to_relocate(dbg, section_index,&relocatablesec,error);
924 if (res != DW_DLV_OK) {
925 return res;
926 }
927
928 /* Sun and possibly others do not always set sh_link in .debug_* sections.
929 So we cannot do full consistency checks. */
930 if (relocatablesec->dss_reloc_index == 0 ) {
931 /* Something is wrong. */
932 *error = DW_DLE_RELOC_SECTION_MISSING_INDEX;
933 return DW_DLV_ERROR;
934 }
935 /* Now load the relocations themselves. */
936 res = dwarf_elf_object_access_load_section(obj_in,
937 relocatablesec->dss_reloc_index,
938 &relocatablesec->dss_reloc_data, error);
939 if (res != DW_DLV_OK) {
940 return res;
941 }
942
943 /* Now get the symtab. */
944 if (!obj->symtab) {
945 obj->symtab = &dbg->de_elf_symtab;
946 obj->strtab = &dbg->de_elf_strtab;
947 }
948 if (obj->symtab->dss_index != relocatablesec->dss_reloc_link) {
949 /* Something is wrong. */
950 *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX;
951 return DW_DLV_ERROR;
952 }
953 if (obj->strtab->dss_index != obj->symtab->dss_link) {
954 /* Something is wrong. */
955 *error = DW_DLE_RELOC_MISMATCH_STRTAB_INDEX;
956 return DW_DLV_ERROR;
957 }
958 if (!obj->symtab->dss_data) {
959 /* Now load the symtab */
960 res = dwarf_elf_object_access_load_section(obj_in,
961 obj->symtab->dss_index,
962 &obj->symtab->dss_data, error);
963 if (res != DW_DLV_OK) {
964 return res;
965 }
966 }
967 if (!obj->strtab->dss_data) {
968 /* Now load the strtab */
969 res = dwarf_elf_object_access_load_section(obj_in,
970 obj->strtab->dss_index,
971 &obj->strtab->dss_data,error);
972 if (res != DW_DLV_OK){
973 return res;
974 }
975 }
976
977
978 /* We have all the data we need in memory. */
979 res = loop_through_relocations(dbg,obj,relocatablesec,error);
980
981 return res;
982 }
983
984 /* dwarf_elf_object_access_load_section()
985 We are only asked to load sections that
986 libdwarf really needs.
987 It would be much better if a 'user data pointer'
988 were passed through these interfaces so one
989 part of libdwarf could pass through to this.
990 Or even just if a Dwarf_Debug were passed in.
991 Sigh. */
992 static int
dwarf_elf_object_access_load_section(void * obj_in,Dwarf_Half section_index,Dwarf_Small ** section_data,int * error)993 dwarf_elf_object_access_load_section(void* obj_in,
994 Dwarf_Half section_index,
995 Dwarf_Small** section_data,
996 int* error)
997 {
998 dwarf_elf_object_access_internals_t*obj =
999 (dwarf_elf_object_access_internals_t*)obj_in;
1000 if (section_index == 0) {
1001 return DW_DLV_NO_ENTRY;
1002 }
1003
1004 {
1005 Elf_Scn *scn = 0;
1006 Elf_Data *data = 0;
1007
1008 scn = elf_getscn(obj->elf, section_index);
1009 if (scn == NULL) {
1010 /* The section_index does not exist or
1011 obj->elf is NULL. */
1012 *error = DW_DLE_MDE;
1013 return DW_DLV_ERROR;
1014 }
1015
1016 /* When using libelf as a producer, section data may be stored
1017 in multiple buffers. In libdwarf however, we only use libelf
1018 as a consumer (there is a dwarf producer API, but it doesn't
1019 use libelf). Because of this, this single call to elf_getdata
1020 will retrieve the entire section in a single contiguous
1021 buffer. */
1022 data = elf_getdata(scn, NULL);
1023 if (data == NULL) {
1024 /* Most likely means that the Elf section header
1025 is damaged/corrupt and the data is
1026 impossible to read into
1027 memory. The size specified in the
1028 Elf section is too large to allocate memory
1029 for so the data could not be loaded. */
1030 *error = DW_DLE_MDE;
1031 return DW_DLV_ERROR;
1032 }
1033 if (!data->d_buf) {
1034 /* If NULL it means 'the section has no data'
1035 according to libelf documentation.
1036 No DWARF-related section should ever have
1037 'no data'. Happens if a section type is
1038 SHT_NOBITS and no section libdwarf
1039 wants to look at should be SHT_NOBITS. */
1040 *error = DW_DLE_MDE;
1041 return DW_DLV_ERROR;
1042 }
1043 *section_data = data->d_buf;
1044 }
1045 return DW_DLV_OK;
1046 }
1047
1048
1049 /* dwarf_elf_access method table for use with libelf.
1050 See also the methods table in dwarf_elfread.c for non-libelf.
1051 */
1052
1053 static const struct Dwarf_Obj_Access_Methods_s dwarf_elf_object_access_methods =
1054 {
1055 dwarf_elf_object_access_get_section_info,
1056 dwarf_elf_object_access_get_byte_order,
1057 dwarf_elf_object_access_get_length_size,
1058 dwarf_elf_object_access_get_pointer_size,
1059 dwarf_elf_object_access_get_section_count,
1060 dwarf_elf_object_access_load_section,
1061 dwarf_elf_object_relocate_a_section
1062 };
1063
1064
1065 /* Interface for the ELF object file implementation.
1066 On error this should set *err with the
1067 libdwarf error code.
1068 */
1069 int
dwarf_elf_object_access_init(dwarf_elf_handle elf,int libdwarf_owns_elf,Dwarf_Obj_Access_Interface ** ret_obj,int * err)1070 dwarf_elf_object_access_init(dwarf_elf_handle elf,
1071 int libdwarf_owns_elf,
1072 Dwarf_Obj_Access_Interface** ret_obj,
1073 int *err)
1074 {
1075 int res = 0;
1076 dwarf_elf_object_access_internals_t *internals = 0;
1077 Dwarf_Obj_Access_Interface *intfc = 0;
1078
1079 internals = malloc(sizeof(dwarf_elf_object_access_internals_t));
1080 if (!internals) {
1081 *err = DW_DLE_ALLOC_FAIL;
1082 /* Impossible case, we hope. Give up. */
1083 return DW_DLV_ERROR;
1084 }
1085 memset(internals,0,sizeof(*internals));
1086 res = dwarf_elf_object_access_internals_init(internals, elf, err);
1087 if (res != DW_DLV_OK){
1088 /* *err is already set. */
1089 free(internals);
1090 return DW_DLV_ERROR;
1091 }
1092 internals->libdwarf_owns_elf = libdwarf_owns_elf;
1093
1094 intfc = malloc(sizeof(Dwarf_Obj_Access_Interface));
1095 if (!intfc) {
1096 /* Impossible case, we hope. Give up. */
1097 *err = DW_DLE_ALLOC_FAIL;
1098 free(internals);
1099 return DW_DLV_ERROR;
1100 }
1101 /* Initialize the interface struct */
1102 intfc->object = internals;
1103 intfc->methods = &dwarf_elf_object_access_methods;
1104
1105 /* An access method hidden from non-elf. Needed to
1106 handle new-ish SHF_COMPRESSED flag in elf. */
1107 _dwarf_get_elf_flags_func_ptr = _dwarf_get_elf_flags_func;
1108
1109
1110 *ret_obj = intfc;
1111 return DW_DLV_OK;
1112 }
1113
1114
1115
1116 /* Clean up the Dwarf_Obj_Access_Interface returned by elf_access_init. */
1117 void
dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface * obj)1118 dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj)
1119 {
1120 if (!obj) {
1121 return;
1122 }
1123 if (obj->object) {
1124 dwarf_elf_object_access_internals_t *internals =
1125 (dwarf_elf_object_access_internals_t *)obj->object;
1126 if (internals->libdwarf_owns_elf){
1127 /* Happens with dwarf_init_path(),
1128 dwarf_init(), or dwarf_init_b()
1129 interfaces. */
1130 elf_end(internals->elf);
1131 }
1132 }
1133 free(obj->object);
1134 free(obj);
1135 }
1136
1137 /* This function returns the Elf * pointer
1138 associated with a Dwarf_Debug.
1139
1140 This function only makes sense if ELF is implied
1141 and there actually is an Elf * pointer available.
1142 */
1143 int
dwarf_get_elf(Dwarf_Debug dbg,dwarf_elf_handle * elf,Dwarf_Error * error)1144 dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf,
1145 Dwarf_Error * error)
1146 {
1147 struct Dwarf_Obj_Access_Interface_s * obj = 0;
1148 if (dbg == NULL) {
1149 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
1150 return (DW_DLV_ERROR);
1151 }
1152
1153 obj = dbg->de_obj_file;
1154 if (obj && obj->object) {
1155 dwarf_elf_object_access_internals_t *internals = 0;
1156 char typeletter = *(char *)(obj->object);
1157
1158 if (typeletter != 'E') {
1159 /* Not libelf Elf */
1160 return DW_DLV_NO_ENTRY;
1161 }
1162 internals = (dwarf_elf_object_access_internals_t*)obj->object;
1163 if (internals->elf == NULL) {
1164 _dwarf_error(dbg, error, DW_DLE_FNO);
1165 return (DW_DLV_ERROR);
1166 }
1167 *elf = internals->elf;
1168 return DW_DLV_OK;
1169 }
1170 _dwarf_error(dbg, error, DW_DLE_FNO);
1171 return DW_DLV_ERROR;
1172 }
1173 #else
1174 int dwarf_elf_access_dummy_var_avoid_warn = 0;
1175 #endif /* DWARF_WITH_LIBELF */
1176