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-2010 David Anderson. All rights reserved.
6 Portions Copyright 2009-2010 Novell Inc. All rights reserved.
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of version 2.1 of the GNU Lesser General Public License
10 as published by the Free Software Foundation.
11
12 This program is distributed in the hope that it would be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 Further, this software is distributed without any warranty that it is
17 free of the rightful claim of any third person regarding infringement
18 or the like. Any license provided herein, whether implied or
19 otherwise, applies only to this software file. Patent licenses, if
20 any, provided herein do not apply to combinations of this program with
21 other software, or any other product whatsoever.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this program; if not, write the Free Software
25 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
26 USA.
27
28 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
29 Mountain View, CA 94043, or:
30
31 http://www.sgi.com
32
33 For further information regarding this notice, see:
34
35 http://oss.sgi.com/projects/GenInfo/NoticeExplan
36
37 */
38
39 #include "config.h"
40 #include "dwarf_incl.h"
41 #include "dwarf_elf_access.h"
42
43 #ifdef HAVE_ELF_H
44 #include <elf.h>
45 #endif
46 #ifdef HAVE_LIBELF_H
47 #include <libelf.h>
48 #else
49 #ifdef HAVE_LIBELF_LIBELF_H
50 #include <libelf/libelf.h>
51 #endif
52 #endif
53
54 #include <stdio.h>
55 #include <sys/stat.h>
56 #include <sys/types.h>
57 #include <string.h>
58 #include <stdlib.h>
59
60 #define FALSE 0
61 #define TRUE 1
62
63 #ifndef EM_MIPS
64 /* This is the standard elf value EM_MIPS. */
65 #define EM_MIPS 8
66 #endif
67
68
69 #ifdef HAVE_ELF64_GETEHDR
70 extern Elf64_Ehdr *elf64_getehdr(Elf *);
71 #endif
72 #ifdef HAVE_ELF64_GETSHDR
73 extern Elf64_Shdr *elf64_getshdr(Elf_Scn *);
74 #endif
75 #ifdef WORDS_BIGENDIAN
76 #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
77 { \
78 dbg->de_copy_word(dest, \
79 ((char *)source) +srclength-len_out, \
80 len_out) ; \
81 }
82
83
84 #else /* LITTLE ENDIAN */
85
86 #define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
87 { \
88 dbg->de_copy_word( (dest) , \
89 ((char *)source) , \
90 len_out) ; \
91 }
92 #endif
93
94
95
96 typedef struct {
97 dwarf_elf_handle elf;
98 int is_64bit;
99 Dwarf_Small length_size;
100 Dwarf_Small pointer_size;
101 Dwarf_Unsigned section_count;
102 Dwarf_Endianness endianness;
103 Dwarf_Small machine;
104 int libdwarf_owns_elf;
105 Elf32_Ehdr *ehdr32;
106
107 #ifdef HAVE_ELF64_GETEHDR
108 Elf64_Ehdr *ehdr64;
109 #endif
110 /* Elf symtab and its strtab. Initialized at first
111 call to do relocations, the actual data is in the Dwarf_Debug
112 struct, not allocated locally here. */
113 struct Dwarf_Section_s *symtab;
114 struct Dwarf_Section_s *strtab;
115
116 } dwarf_elf_object_access_internals_t;
117
118 struct Dwarf_Elf_Rela {
119 Dwarf_ufixed64 r_offset;
120 /*Dwarf_ufixed64 r_info; */
121 Dwarf_ufixed64 r_type;
122 Dwarf_ufixed64 r_symidx;
123 Dwarf_ufixed64 r_addend;
124 };
125
126
127 static int dwarf_elf_object_access_load_section(void* obj_in,
128 Dwarf_Half section_index,
129 Dwarf_Small** section_data,
130 int* error);
131
132 /*
133 dwarf_elf_object_access_internals_init()
134 */
135 static int
dwarf_elf_object_access_internals_init(void * obj_in,dwarf_elf_handle elf,int * error)136 dwarf_elf_object_access_internals_init(void* obj_in,
137 dwarf_elf_handle elf,
138 int* error)
139 {
140 dwarf_elf_object_access_internals_t*obj =
141 (dwarf_elf_object_access_internals_t*)obj_in;
142 char *ehdr_ident = 0;
143 Dwarf_Half machine = 0;
144 obj->elf = elf;
145
146 if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {
147 *error = DW_DLE_ELF_GETIDENT_ERROR;
148 return DW_DLV_ERROR;
149 }
150
151 obj->is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64);
152
153
154 if(ehdr_ident[EI_DATA] == ELFDATA2LSB){
155 obj->endianness = DW_OBJECT_LSB;
156 }
157 else if(ehdr_ident[EI_DATA] == ELFDATA2MSB){
158 obj->endianness = DW_OBJECT_MSB;
159 }
160
161 if (obj->is_64bit) {
162 #ifdef HAVE_ELF64_GETEHDR
163 obj->ehdr64 = elf64_getehdr(elf);
164 if (obj->ehdr64 == NULL) {
165 *error = DW_DLE_ELF_GETEHDR_ERROR;
166 return DW_DLV_ERROR;
167 }
168 obj->section_count = obj->ehdr64->e_shnum;
169 machine = obj->ehdr64->e_machine;
170 obj->machine = machine;
171 #else
172 *error = DW_DLE_NO_ELF64_SUPPORT;
173 return DW_DLV_ERROR;
174 #endif
175 }
176 else {
177 obj->ehdr32 = elf32_getehdr(elf);
178 if (obj->ehdr32 == NULL) {
179 *error = DW_DLE_ELF_GETEHDR_ERROR;
180 return DW_DLV_ERROR;
181 }
182 obj->section_count = obj->ehdr32->e_shnum;
183 machine = obj->ehdr32->e_machine;
184 obj->machine = machine;
185 }
186
187 /* The following length_size is Not Too Significant. Only used
188 one calculation, and an approximate one at that. */
189 obj->length_size = obj->is_64bit ? 8 : 4;
190 obj->pointer_size = obj->is_64bit ? 8 : 4;
191
192 if (obj->is_64bit && machine != EM_MIPS) {
193 /* MIPS/IRIX makes pointer size and length size 8 for -64.
194 Other platforms make length 4 always. */
195 /* 4 here supports 32bit-offset dwarf2, as emitted by cygnus
196 tools, and the dwarfv2.1 64bit extension setting.
197 This is not the same as the size-of-an-offset, which
198 is 4 in 32bit dwarf and 8 in 64bit dwarf. */
199 obj->length_size = 4;
200 }
201 return DW_DLV_OK;
202 }
203
204 /*
205 dwarf_elf_object_access_get_byte_order
206 */
207 static
208 Dwarf_Endianness
dwarf_elf_object_access_get_byte_order(void * obj_in)209 dwarf_elf_object_access_get_byte_order(void* obj_in)
210 {
211 dwarf_elf_object_access_internals_t*obj =
212 (dwarf_elf_object_access_internals_t*)obj_in;
213 return obj->endianness;
214 }
215
216 /*
217 dwarf_elf_object_access_get_section_count()
218 */
219 static
220 Dwarf_Unsigned
dwarf_elf_object_access_get_section_count(void * obj_in)221 dwarf_elf_object_access_get_section_count(void * obj_in)
222 {
223 dwarf_elf_object_access_internals_t*obj =
224 (dwarf_elf_object_access_internals_t*)obj_in;
225 return obj->section_count;
226 }
227
228
229 /*
230 dwarf_elf_object_access_get_section()
231 */
232 static
233 int
dwarf_elf_object_access_get_section_info(void * obj_in,Dwarf_Half section_index,Dwarf_Obj_Access_Section * ret_scn,int * error)234 dwarf_elf_object_access_get_section_info(
235 void* obj_in,
236 Dwarf_Half section_index,
237 Dwarf_Obj_Access_Section* ret_scn,
238 int* error)
239 {
240 dwarf_elf_object_access_internals_t*obj =
241 (dwarf_elf_object_access_internals_t*)obj_in;
242
243 Elf32_Shdr *shdr32 = 0;
244
245 #ifdef HAVE_ELF64_GETSHDR
246 Elf64_Shdr *shdr64 = 0;
247 #endif
248 Elf_Scn *scn = 0;
249
250
251 scn = elf_getscn(obj->elf, section_index);
252 if (scn == NULL) {
253 *error = DW_DLE_MDE;
254 return DW_DLV_ERROR;
255 }
256 if (obj->is_64bit) {
257 #ifdef HAVE_ELF64_GETSHDR
258 shdr64 = elf64_getshdr(scn);
259 if (shdr64 == NULL) {
260 *error = DW_DLE_ELF_GETSHDR_ERROR;
261 return DW_DLV_ERROR;
262 }
263
264 ret_scn->size = shdr64->sh_size;
265 ret_scn->addr = shdr64->sh_addr;
266 ret_scn->link = shdr64->sh_link;
267
268 ret_scn->name = elf_strptr(obj->elf, obj->ehdr64->e_shstrndx,
269 shdr64->sh_name);
270 if(ret_scn->name == NULL) {
271 *error = DW_DLE_ELF_STRPTR_ERROR;
272 return DW_DLV_ERROR;
273 }
274 return DW_DLV_OK;
275 #else
276 *error = DW_DLE_MISSING_ELF64_SUPPORT;
277 return DW_DLV_ERROR;
278 #endif /* HAVE_ELF64_GETSHDR */
279 }
280 if ((shdr32 = elf32_getshdr(scn)) == NULL) {
281 *error = DW_DLE_ELF_GETSHDR_ERROR;
282 return DW_DLV_ERROR;
283 }
284
285 ret_scn->size = shdr32->sh_size;
286 ret_scn->addr = shdr32->sh_addr;
287 ret_scn->link = shdr32->sh_link;
288
289 ret_scn->name = elf_strptr(obj->elf, obj->ehdr32->e_shstrndx,
290 shdr32->sh_name);
291 if (ret_scn->name == NULL) {
292 *error = DW_DLE_ELF_STRPTR_ERROR;
293 return DW_DLV_ERROR;
294 }
295 return DW_DLV_OK;
296 }
297
298 /*
299 dwarf_elf_object_access_get_length_size
300 */
301 static
302 Dwarf_Small
dwarf_elf_object_access_get_length_size(void * obj_in)303 dwarf_elf_object_access_get_length_size(void* obj_in)
304 {
305 dwarf_elf_object_access_internals_t*obj =
306 (dwarf_elf_object_access_internals_t*)obj_in;
307 return obj->length_size;
308 }
309
310 /*
311 dwarf_elf_object_access_get_pointer_size
312 */
313 static
314 Dwarf_Small
dwarf_elf_object_access_get_pointer_size(void * obj_in)315 dwarf_elf_object_access_get_pointer_size(void* obj_in)
316 {
317 dwarf_elf_object_access_internals_t*obj =
318 (dwarf_elf_object_access_internals_t*)obj_in;
319 return obj->pointer_size;
320 }
321
322 #define MATCH_REL_SEC(i_,s_,r_) \
323 if(i_ == s_.dss_index) { \
324 *r_ = &s_; \
325 return DW_DLV_OK; \
326 }
327
328 static int
find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index,struct Dwarf_Section_s ** relocatablesec,int * error)329 find_section_to_relocate(Dwarf_Debug dbg,Dwarf_Half section_index,
330 struct Dwarf_Section_s **relocatablesec, int *error)
331 {
332 MATCH_REL_SEC(section_index,dbg->de_debug_info,relocatablesec);
333 MATCH_REL_SEC(section_index,dbg->de_debug_abbrev,relocatablesec);
334 MATCH_REL_SEC(section_index,dbg->de_debug_line,relocatablesec);
335 MATCH_REL_SEC(section_index,dbg->de_debug_loc,relocatablesec);
336 MATCH_REL_SEC(section_index,dbg->de_debug_aranges,relocatablesec);
337 MATCH_REL_SEC(section_index,dbg->de_debug_macinfo,relocatablesec);
338 MATCH_REL_SEC(section_index,dbg->de_debug_pubnames,relocatablesec);
339 MATCH_REL_SEC(section_index,dbg->de_debug_ranges,relocatablesec);
340 MATCH_REL_SEC(section_index,dbg->de_debug_frame,relocatablesec);
341 MATCH_REL_SEC(section_index,dbg->de_debug_frame_eh_gnu,relocatablesec);
342 MATCH_REL_SEC(section_index,dbg->de_debug_pubtypes,relocatablesec);
343 MATCH_REL_SEC(section_index,dbg->de_debug_funcnames,relocatablesec);
344 MATCH_REL_SEC(section_index,dbg->de_debug_typenames,relocatablesec);
345 MATCH_REL_SEC(section_index,dbg->de_debug_varnames,relocatablesec);
346 MATCH_REL_SEC(section_index,dbg->de_debug_weaknames,relocatablesec);
347 /* dbg-> de_debug_str,syms); */
348 /* de_elf_symtab,syms); */
349 /* de_elf_strtab,syms); */
350 *error = DW_DLE_RELOC_SECTION_MISMATCH;
351 return DW_DLV_ERROR;
352
353 }
354 #undef MATCH_REL_SEC
355
356 static void
get_rela_elf32(Dwarf_Small * data,unsigned int i,int endianness,int machine,struct Dwarf_Elf_Rela * relap)357 get_rela_elf32(Dwarf_Small *data, unsigned int i,
358 int endianness,
359 int machine, struct Dwarf_Elf_Rela *relap)
360 {
361 Elf32_Rela *relp = (Elf32_Rela*)(data + (i * sizeof(Elf32_Rela)));
362 relap->r_offset = relp->r_offset;
363 /*
364 relap->r_info = relp->r_info;
365 */
366 relap->r_type = ELF32_R_TYPE(relp->r_info);
367 relap->r_symidx = ELF32_R_SYM(relp->r_info);
368 relap->r_addend = relp->r_addend;
369 }
370
371 static void
get_rela_elf64(Dwarf_Small * data,unsigned int i,int endianness,int machine,struct Dwarf_Elf_Rela * relap)372 get_rela_elf64(Dwarf_Small *data, unsigned int i,
373 int endianness,
374 int machine,struct Dwarf_Elf_Rela *relap)
375 {
376 #ifdef HAVE_ELF64_RELA
377 Elf64_Rela * relp = (Elf64_Rela*)(data + (i * sizeof(Elf64_Rela)));
378 relap->r_offset = relp->r_offset;
379 /*
380 relap->r_info = relp->r_info;
381 */
382 if(machine == EM_MIPS && endianness == DW_OBJECT_LSB ) {
383 /* This is really wierd. Treat this very specially.
384 The Elf64 LE MIPS object used for
385 testing (that has rela) wants the
386 values as sym ssym type3 type2 type, treating
387 each value as independent value. But libelf xlate
388 treats it as something else so we fudge here.
389 It is unclear
390 how to precisely characterize where these relocations
391 were used.
392 SGI MIPS on IRIX never used .rela relocations.
393 The BE 64bit elf MIPS test object with rela uses traditional
394 elf relocation layouts, not this special case. */
395 #define ELF64MIPS_REL_SYM(i) ((i) & 0xffffffff)
396 #define ELF64MIPS_REL_TYPE(i) ((i >> 56) &0xff)
397 /* We ignore the special TYPE2 and TYPE3, they should be
398 value R_MIPS_NONE in rela. */
399 relap->r_type = ELF64MIPS_REL_TYPE(relp->r_info);
400 relap->r_symidx = ELF64MIPS_REL_SYM(relp->r_info);
401 #undef MIPS64SYM
402 #undef MIPS64TYPE
403 } else
404 {
405 relap->r_type = ELF64_R_TYPE(relp->r_info);
406 relap->r_symidx = ELF64_R_SYM(relp->r_info);
407 }
408 relap->r_addend = relp->r_addend;
409 #endif
410 }
411
412 static void
get_relocations_array(Dwarf_Bool is_64bit,int endianness,int machine,Dwarf_Small * data,unsigned int num_relocations,struct Dwarf_Elf_Rela * relap)413 get_relocations_array(Dwarf_Bool is_64bit,
414 int endianness,
415 int machine,
416 Dwarf_Small *data,
417 unsigned int num_relocations,
418 struct Dwarf_Elf_Rela *relap)
419 {
420 unsigned int i = 0;
421 void (*get_relocations)(Dwarf_Small *data, unsigned int i,
422 int endianness,
423 int machine,
424 struct Dwarf_Elf_Rela *relap);
425
426 /* Handle 32/64 bit issue
427 */
428 if (is_64bit) {
429 get_relocations = get_rela_elf64;
430 } else {
431 get_relocations = get_rela_elf32;
432 }
433
434 for (i=0; i < num_relocations; i++) {
435 get_relocations(data, i,endianness,machine, &(relap[i]));
436 }
437
438 }
439
440 static int
get_relocation_entries(Dwarf_Bool is_64bit,int endianness,int machine,Dwarf_Small * relocation_section,Dwarf_Unsigned relocation_section_size,struct Dwarf_Elf_Rela ** relas,unsigned int * nrelas,int * error)441 get_relocation_entries(Dwarf_Bool is_64bit,
442 int endianness,
443 int machine,
444 Dwarf_Small *relocation_section,
445 Dwarf_Unsigned relocation_section_size,
446 struct Dwarf_Elf_Rela **relas,
447 unsigned int *nrelas,
448 int *error)
449 {
450 unsigned int relocation_size = 0;
451
452 if (is_64bit) {
453 #ifdef HAVE_ELF64_RELA
454 relocation_size = sizeof(Elf64_Rela);
455 #else
456 *error = DW_DLE_MISSING_ELF64_SUPPORT;
457 return DW_DLV_ERROR;
458 #endif
459 } else {
460 relocation_size = sizeof(Elf32_Rela);
461 }
462
463 if (relocation_section == NULL) {
464 *error = DW_DLE_RELOC_SECTION_PTR_NULL;
465 return(DW_DLV_ERROR);
466 }
467
468 if ((relocation_section_size != 0)) {
469 size_t bytescount = 0;
470 if(relocation_section_size%relocation_size) {
471 *error = DW_DLE_RELOC_SECTION_LENGTH_ODD;
472 return DW_DLV_ERROR;
473 }
474 *nrelas = relocation_section_size/relocation_size;
475 bytescount = (*nrelas) * sizeof(struct Dwarf_Elf_Rela);
476 *relas = malloc(bytescount);
477 if (!*relas) {
478 *error = DW_DLE_MAF;
479 return(DW_DLV_ERROR);
480 }
481 memset(*relas,0,bytescount);
482 get_relocations_array(is_64bit,endianness,machine, relocation_section,
483 *nrelas, *relas);
484 }
485 return(DW_DLV_OK);
486 }
487
488 static Dwarf_Bool
is_32bit_abs_reloc(unsigned int type,Dwarf_Half machine)489 is_32bit_abs_reloc(unsigned int type, Dwarf_Half machine)
490 {
491 Dwarf_Bool r = 0;
492 switch (machine) {
493 #if defined(EM_MIPS) && defined (R_MIPS_32)
494 case EM_MIPS:
495 r = (type == R_MIPS_32);
496 break;
497 #endif
498 #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA32)
499 case EM_SPARC32PLUS:
500 r = (type == R_SPARC_UA32);
501 break;
502 #endif
503 #if defined(EM_SPARCV9) && defined (R_SPARC_UA32)
504 case EM_SPARCV9:
505 r = (type == R_SPARC_UA32);
506 break;
507 #endif
508 #if defined(EM_SPARC) && defined (R_SPARC_UA32)
509 case EM_SPARC:
510 r = (type == R_SPARC_UA32);
511 break;
512 #endif
513 #if defined(EM_386) && defined (R_386_32)
514 case EM_386:
515 r = (type == R_386_32);
516 break;
517 #endif
518 #if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB)
519 case EM_IA_64:
520 r = (type == R_IA64_SECREL32LSB);
521 break;
522 #endif
523 #if defined(EM_PPC64) && defined (R_PPC64_ADDR32)
524 case EM_PPC64:
525 r = (type == R_PPC64_ADDR32);
526 break;
527 #endif
528 #if defined(EM_PPC) && defined (R_PPC_ADDR32)
529 case EM_PPC:
530 r = (type == R_PPC_ADDR32);
531 break;
532 #endif
533 #if defined(EM_S390) && defined (R_390_32)
534 case EM_S390:
535 r = (type == R_390_32);
536 break;
537 #endif
538 #if defined(EM_X86_64) && defined (R_X86_64_32)
539 case EM_X86_64:
540 r = (type == R_X86_64_32);
541 break;
542 #endif
543 }
544 return r;
545 }
546
547 static Dwarf_Bool
is_64bit_abs_reloc(unsigned int type,Dwarf_Half machine)548 is_64bit_abs_reloc(unsigned int type, Dwarf_Half machine)
549 {
550 Dwarf_Bool r = 0;
551 switch (machine) {
552 #if defined(EM_MIPS) && defined (R_MIPS_64)
553 case EM_MIPS:
554 r = (type == R_MIPS_64);
555 break;
556 #endif
557 #if defined(EM_SPARC32PLUS) && defined (R_SPARC_UA64)
558 case EM_SPARC32PLUS:
559 r = (type == R_SPARC_UA64);
560 break;
561 #endif
562 #if defined(EM_SPARCV9) && defined (R_SPARC_UA64)
563 case EM_SPARCV9:
564 r = (type == R_SPARC_UA64);
565 break;
566 #endif
567 #if defined(EM_SPARC) && defined (R_SPARC_UA64)
568 case EM_SPARC:
569 r = (type == R_SPARC_UA64);
570 break;
571 #endif
572 #if defined(EM_IA_64) && defined (R_IA64_SECREL32LSB)
573 case EM_IA_64:
574 r = (type == R_IA64_DIR64LSB);
575 break;
576 #endif
577 #if defined(EM_PPC64) && defined (R_PPC64_ADDR64)
578 case EM_PPC64:
579 r = (type == R_PPC64_ADDR64);
580 break;
581 #endif
582 #if defined(EM_S390) && defined (R_390_64)
583 case EM_S390:
584 r = (type == R_390_64);
585 break;
586 #endif
587 #if defined(EM_X86_64) && defined (R_X86_64_64)
588 case EM_X86_64:
589 r = (type == R_X86_64_64);
590 break;
591 #endif
592 }
593 return r;
594 }
595
596
597 static void
update_entry(Dwarf_Debug dbg,Dwarf_Bool is_64bit,Dwarf_Endianness endianess,Dwarf_Half machine,struct Dwarf_Elf_Rela * rela,Dwarf_Small * target_section,Dwarf_Small * section_data)598 update_entry(Dwarf_Debug dbg,
599 Dwarf_Bool is_64bit, Dwarf_Endianness endianess,
600 Dwarf_Half machine, struct Dwarf_Elf_Rela *rela,
601 Dwarf_Small *target_section, Dwarf_Small *section_data)
602 {
603 unsigned int type = 0;
604 unsigned int sym_idx = 0;
605 #ifdef HAVE_ELF64_SYM
606 Elf64_Sym sym_buf;
607 Elf64_Sym *sym = 0;
608 #else
609 Elf32_Sym sym_buf;
610 Elf32_Sym *sym = 0;
611 #endif
612 Elf32_Sym *sym32 = 0;
613 Dwarf_ufixed64 offset = 0;
614 Dwarf_sfixed64 addend = 0;
615 Dwarf_Unsigned reloc_size = 0;
616
617
618 /* Dwarf_Elf_Rela dereferencing */
619 offset = rela->r_offset;
620 addend = rela->r_addend;
621 type = rela->r_type;
622 sym_idx = rela->r_symidx;
623
624 if (is_64bit) {
625 #ifdef HAVE_ELF64_SYM
626 sym = &((Elf64_Sym*)section_data)[sym_idx];
627 #endif
628 } else {
629 sym32 = &((Elf32_Sym*)section_data)[sym_idx];
630
631 /* Convert Elf32_Sym struct to Elf64_Sym struct. We point at
632 * an Elf64_Sym local variable (sym_buf) to allow us to use the
633 * same pointer (sym) for both 32-bit and 64-bit instances.
634 */
635 sym = &sym_buf;
636 sym->st_name = sym32->st_name;
637 sym->st_info = sym32->st_info;
638 sym->st_other = sym32->st_other;
639 sym->st_shndx = sym32->st_shndx;
640 sym->st_value = sym32->st_value;
641 sym->st_size = sym32->st_size;
642 }
643
644 /* Determine relocation size */
645 if (is_32bit_abs_reloc(type, machine)) {
646 reloc_size = 4;
647 } else if (is_64bit_abs_reloc(type, machine)) {
648 reloc_size = 8;
649 } else {
650 return;
651 }
652
653
654 {
655 /* Assuming we do not need to do a READ_UNALIGNED here
656 at target_section + offset and add its value to
657 outval. Some ABIs say no read (for example MIPS),
658 but if some do then which ones? */
659 Dwarf_Unsigned outval = sym->st_value + addend;
660 WRITE_UNALIGNED(dbg,target_section + offset,
661 &outval,sizeof(outval),reloc_size);
662 }
663 }
664
665
666
667 static int
apply_rela_entries(Dwarf_Debug dbg,Dwarf_Bool is_64bit,Dwarf_Endianness endianess,Dwarf_Half machine,Dwarf_Small * target_section,Dwarf_Small * symtab_section,struct Dwarf_Elf_Rela * relas,unsigned int nrelas,int * error)668 apply_rela_entries(Dwarf_Debug dbg,
669 Dwarf_Bool is_64bit,
670 Dwarf_Endianness endianess,
671 Dwarf_Half machine,
672 Dwarf_Small *target_section,
673 Dwarf_Small *symtab_section,
674 struct Dwarf_Elf_Rela *relas, unsigned int nrelas,
675 int *error)
676 {
677 if ((target_section != NULL) && (relas != NULL)) {
678 unsigned int i;
679 for (i = 0; i < nrelas; i++) {
680 update_entry(dbg, is_64bit,
681 endianess,
682 machine,
683 &(relas)[i],
684 target_section,
685 symtab_section);
686 }
687 }
688 return DW_DLV_OK;
689 }
690
691
692 static int
loop_through_relocations(Dwarf_Debug dbg,dwarf_elf_object_access_internals_t * obj,struct Dwarf_Section_s * relocatablesec,int * error)693 loop_through_relocations(
694 Dwarf_Debug dbg,
695 dwarf_elf_object_access_internals_t* obj,
696 struct Dwarf_Section_s *relocatablesec,
697 int *error)
698 {
699 Dwarf_Small *target_section = 0;
700 Dwarf_Small *symtab_section = obj->symtab->dss_data;
701 Dwarf_Small *relocation_section = relocatablesec->dss_reloc_data;
702 Dwarf_Unsigned relocation_section_size =
703 relocatablesec->dss_reloc_size;
704 int ret = DW_DLV_ERROR;
705 struct Dwarf_Elf_Rela *relas = 0;
706 unsigned int nrelas = 0;
707 Dwarf_Small *mspace = 0;
708
709 ret = get_relocation_entries(obj->is_64bit,
710 obj->endianness,
711 obj->machine,
712 relocation_section,
713 relocation_section_size,
714 &relas, &nrelas, error);
715 if(ret != DW_DLV_OK) {
716 free(relas);
717 return ret;
718 }
719
720 /* Some systems read Elf in read-only memory via mmap or the like.
721 So the only safe thing is to copy the current data into
722 malloc space and refer to the malloc space instead of the
723 space returned by the elf library */
724 mspace = malloc(relocatablesec->dss_size);
725 if(!mspace) {
726 *error = DW_DLE_RELOC_SECTION_MALLOC_FAIL;
727 return DW_DLV_ERROR;
728 }
729 memcpy(mspace,relocatablesec->dss_data,relocatablesec->dss_size);
730 relocatablesec->dss_data = mspace;
731 target_section = relocatablesec->dss_data;
732 relocatablesec->dss_data_was_malloc = 1;
733
734 ret = apply_rela_entries(
735 dbg,
736 obj->is_64bit,
737 obj->endianness, obj->machine,
738 target_section,
739 symtab_section,
740 relas, nrelas, error);
741
742 free(relas);
743
744 return ret;
745 }
746
747 /*
748 Find the section data in dbg and find all the relevant
749 sections. Then do relocations.
750 */
751 static int
dwarf_elf_object_relocate_a_section(void * obj_in,Dwarf_Half section_index,Dwarf_Debug dbg,int * error)752 dwarf_elf_object_relocate_a_section(void* obj_in,
753 Dwarf_Half section_index,
754 Dwarf_Debug dbg,
755 int* error)
756 {
757 int res = DW_DLV_ERROR;
758 dwarf_elf_object_access_internals_t*obj = 0;
759 struct Dwarf_Section_s * relocatablesec = 0;
760 if (section_index == 0) {
761 return DW_DLV_NO_ENTRY;
762 }
763 obj = (dwarf_elf_object_access_internals_t*)obj_in;
764
765 /* The section to relocate must already be loaded into memory. */
766 res = find_section_to_relocate(dbg, section_index,&relocatablesec,error);
767 if(res != DW_DLV_OK) {
768 return res;
769 }
770
771 /* Sun and possibly others do not always set sh_link in .debug_* sections.
772 So we cannot do full consistency checks. */
773 if(relocatablesec->dss_reloc_index == 0 ) {
774 /* Something is wrong. */
775 *error = DW_DLE_RELOC_SECTION_MISSING_INDEX;
776 return DW_DLV_ERROR;
777 }
778 /* Now load the relocations themselves. */
779 res = dwarf_elf_object_access_load_section(obj_in,
780 relocatablesec->dss_reloc_index,
781 &relocatablesec->dss_reloc_data, error);
782 if(res != DW_DLV_OK) {
783 return res;
784 }
785
786 /* Now get the symtab. */
787 if (!obj->symtab) {
788 obj->symtab = &dbg->de_elf_symtab;
789 obj->strtab = &dbg->de_elf_strtab;
790 }
791 if( obj->symtab->dss_index != relocatablesec->dss_reloc_link) {
792 /* Something is wrong. */
793 *error = DW_DLE_RELOC_MISMATCH_RELOC_INDEX;
794 return DW_DLV_ERROR;
795 }
796 if( obj->strtab->dss_index != obj->symtab->dss_link) {
797 /* Something is wrong. */
798 *error = DW_DLE_RELOC_MISMATCH_STRTAB_INDEX;
799 return DW_DLV_ERROR;
800 }
801 if(!obj->symtab->dss_data) {
802 /* Now load the symtab */
803 res = dwarf_elf_object_access_load_section(obj_in,
804 obj->symtab->dss_index,
805 &obj->symtab->dss_data, error);
806 if(res != DW_DLV_OK) {
807 return res;
808 }
809 }
810 if(! obj->strtab->dss_data) {
811 /* Now load the strtab */
812 res = dwarf_elf_object_access_load_section(obj_in,
813 obj->strtab->dss_index,
814 &obj->strtab->dss_data,error);
815 if(res != DW_DLV_OK){
816 return res;
817 }
818 }
819
820 /* We have all the data we need in memory. */
821 res = loop_through_relocations(dbg,obj,relocatablesec,error);
822
823 return res;
824 }
825
826 /*
827 dwarf_elf_object_access_load_section
828 */
829 static int
dwarf_elf_object_access_load_section(void * obj_in,Dwarf_Half section_index,Dwarf_Small ** section_data,int * error)830 dwarf_elf_object_access_load_section(void* obj_in,
831 Dwarf_Half section_index,
832 Dwarf_Small** section_data,
833 int* error)
834 {
835 dwarf_elf_object_access_internals_t*obj =
836 (dwarf_elf_object_access_internals_t*)obj_in;
837 if (section_index == 0) {
838 return DW_DLV_NO_ENTRY;
839 }
840
841 {
842 Elf_Scn *scn = 0;
843 Elf_Data *data = 0;
844
845 scn = elf_getscn(obj->elf, section_index);
846 if (scn == NULL) {
847 *error = DW_DLE_MDE;
848 return DW_DLV_ERROR;
849 }
850
851 /*
852 When using libelf as a producer, section data may be stored
853 in multiple buffers. In libdwarf however, we only use libelf
854 as a consumer (there is a dwarf producer API, but it doesn't
855 use libelf). Because of this, this single call to elf_getdata
856 will retrieve the entire section in a single contiguous
857 buffer. */
858 data = elf_getdata(scn, NULL);
859 if (data == NULL) {
860 *error = DW_DLE_MDE;
861 return DW_DLV_ERROR;
862 }
863 *section_data = data->d_buf;
864 }
865 return DW_DLV_OK;
866 }
867
868
869 /* dwarf_elf_access method table. */
870 static const struct Dwarf_Obj_Access_Methods_s dwarf_elf_object_access_methods =
871 {
872 dwarf_elf_object_access_get_section_info,
873 dwarf_elf_object_access_get_byte_order,
874 dwarf_elf_object_access_get_length_size,
875 dwarf_elf_object_access_get_pointer_size,
876 dwarf_elf_object_access_get_section_count,
877 dwarf_elf_object_access_load_section,
878 dwarf_elf_object_relocate_a_section
879 };
880
881
882 /*
883 Interface for the ELF object file implementation.
884 */
885 int
dwarf_elf_object_access_init(dwarf_elf_handle elf,int libdwarf_owns_elf,Dwarf_Obj_Access_Interface ** ret_obj,int * err)886 dwarf_elf_object_access_init(dwarf_elf_handle elf,
887 int libdwarf_owns_elf,
888 Dwarf_Obj_Access_Interface** ret_obj,
889 int *err)
890 {
891 int res = 0;
892 dwarf_elf_object_access_internals_t *internals = 0;
893 Dwarf_Obj_Access_Interface *intfc = 0;
894
895 internals = malloc(sizeof(dwarf_elf_object_access_internals_t));
896 if(!internals) {
897 /* Impossible case, we hope. Give up. */
898 return DW_DLV_ERROR;
899 }
900 memset(internals,0,sizeof(*internals));
901 res = dwarf_elf_object_access_internals_init(internals, elf, err);
902 if(res != DW_DLV_OK){
903 free(internals);
904 return DW_DLV_ERROR;
905 }
906 internals->libdwarf_owns_elf = libdwarf_owns_elf;
907
908 intfc = malloc(sizeof(Dwarf_Obj_Access_Interface));
909 if(!intfc) {
910 /* Impossible case, we hope. Give up. */
911 free(internals);
912 return DW_DLV_ERROR;
913 }
914 /* Initialize the interface struct */
915 intfc->object = internals;
916 intfc->methods = &dwarf_elf_object_access_methods;
917
918 *ret_obj = intfc;
919 return DW_DLV_OK;
920 }
921
922
923
924 /*
925 Clean up the Dwarf_Obj_Access_Interface returned by elf_access_init.
926 */
927 void
dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface * obj)928 dwarf_elf_object_access_finish(Dwarf_Obj_Access_Interface* obj)
929 {
930 if(!obj) {
931 return;
932 }
933 if(obj->object) {
934 dwarf_elf_object_access_internals_t *internals =
935 (dwarf_elf_object_access_internals_t *)obj->object;
936 if(internals->libdwarf_owns_elf){
937 elf_end(internals->elf);
938 }
939 }
940 free(obj->object);
941 free(obj);
942 }
943
944 /*
945 This function returns the Elf * pointer
946 associated with a Dwarf_Debug.
947
948 This function only makes sense if ELF is implied.
949 */
950 int
dwarf_get_elf(Dwarf_Debug dbg,dwarf_elf_handle * elf,Dwarf_Error * error)951 dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf,
952 Dwarf_Error * error)
953 {
954 struct Dwarf_Obj_Access_Interface_s * obj = 0;
955 if (dbg == NULL) {
956 _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
957 return (DW_DLV_ERROR);
958 }
959
960 obj = dbg->de_obj_file;
961 if(obj) {
962 dwarf_elf_object_access_internals_t *internals =
963 (dwarf_elf_object_access_internals_t*)obj->object;
964 if(internals->elf == NULL) {
965 _dwarf_error(dbg, error, DW_DLE_FNO);
966 return (DW_DLV_ERROR);
967 }
968 *elf = internals->elf;
969 return DW_DLV_OK;
970
971 }
972 _dwarf_error(dbg, error, DW_DLE_FNO);
973 return DW_DLV_ERROR;
974 }
975
976
977