Build fixes for static linked Dyninst components (compute node linux), when linking...
[dyninst.git] / common / src / Elf_X.C
1 /*
2  * Copyright (c) 1996-2011 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #include "common/h/Elf_X.h"
33
34 #include <sys/mman.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <fcntl.h>
38 #include <unistd.h>
39 #include <libgen.h>
40
41 #include <boost/crc.hpp>
42 #include <boost/assign/list_of.hpp>
43 #include <boost/assign/std/set.hpp>
44 #include <boost/assign/std/vector.hpp>
45
46 using namespace std;
47 using boost::crc_32_type;
48 using namespace boost::assign;
49
50 #define DEBUGLINK_NAME ".gnu_debuglink"
51 #define BUILD_ID_NAME ".note.gnu.build-id"
52
53 #if defined(INLINE_ELF_X)
54 #define INLINE_DEF inline
55 #else
56 #define INLINE_DEF
57 #endif
58 // ------------------------------------------------------------------------
59 // Class Elf_X simulates the Elf(32|64)_Ehdr structure.
60 // Also works for ELF archives. 
61 INLINE_DEF Elf_X::Elf_X()
62     : elf(NULL), ehdr32(NULL), ehdr64(NULL), phdr32(NULL), phdr64(NULL),
63       filedes(-1), is64(false), isArchive(false)
64 { }
65
66 INLINE_DEF Elf_X::Elf_X(int input, Elf_Cmd cmd, Elf_X *ref)
67     : ehdr32(NULL), ehdr64(NULL), phdr32(NULL), phdr64(NULL),
68       filedes(input), is64(false), isArchive(false)
69 {
70     if (elf_version(EV_CURRENT) != EV_NONE) {
71         elf_errno(); // Reset elf_errno to zero.
72         if (ref)
73             elf = elf_begin(input, cmd, ref->e_elfp());
74         else
75             elf = elf_begin(input, cmd, NULL);
76         int errnum;
77         if ((errnum = elf_errno()) != 0) {
78             //const char *msg = elf_errmsg(errnum);
79             //fprintf(stderr, "Elf error: %s\n", msg);
80         }
81         if (elf) {
82             if (elf_kind(elf) == ELF_K_ELF) {
83                 char *identp = elf_getident(elf, NULL);
84                 is64 = (identp && identp[EI_CLASS] == ELFCLASS64);
85             }
86             else if(elf_kind(elf) == ELF_K_AR) {
87                 char *identp = elf_getident(elf, NULL);
88                 is64 = (identp && identp[EI_CLASS] == ELFCLASS64);
89                 isArchive = true;
90             }
91
92             if (!is64) ehdr32 = elf32_getehdr(elf);
93             else       ehdr64 = elf64_getehdr(elf);
94
95             if (!is64) phdr32 = elf32_getphdr(elf);
96             else       phdr64 = elf64_getphdr(elf);
97         }
98     }
99 }
100
101 INLINE_DEF Elf_X::Elf_X(char *mem_image, size_t mem_size)
102     : ehdr32(NULL), ehdr64(NULL), phdr32(NULL), phdr64(NULL),
103       is64(false), isArchive(false)
104 {
105     if (elf_version(EV_CURRENT) != EV_NONE) {
106         elf_errno(); // Reset elf_errno to zero.
107         elf = elf_memory(mem_image, mem_size);
108
109         int err;
110         if ( (err = elf_errno()) != 0) {
111             //const char *msg = elf_errmsg(err);
112         }
113
114         if (elf) {
115             if (elf_kind(elf) == ELF_K_ELF) {
116                 char *identp = elf_getident(elf, NULL);
117                 is64 = (identp && identp[EI_CLASS] == ELFCLASS64);
118             }
119
120             if (!is64) ehdr32 = elf32_getehdr(elf);
121             else       ehdr64 = elf64_getehdr(elf);
122
123             if (!is64) phdr32 = elf32_getphdr(elf);
124             else       phdr64 = elf64_getphdr(elf);
125         }
126     }
127 }
128
129 INLINE_DEF void Elf_X::end()
130 {
131     if (elf) {
132         elf_end(elf);
133         elf = NULL;
134         ehdr32 = NULL;
135         ehdr64 = NULL;
136         phdr32 = NULL;
137         phdr64 = NULL;
138     }
139 }
140
141 // Read Interface
142 INLINE_DEF Elf *Elf_X::e_elfp() const
143 {
144     return elf;
145 }
146
147 INLINE_DEF unsigned char *Elf_X::e_ident() const
148 {
149     return (!is64 ?
150             static_cast<unsigned char*>(ehdr32->e_ident) :
151             static_cast<unsigned char*>(ehdr64->e_ident));
152 }
153
154 INLINE_DEF unsigned short Elf_X::e_type() const
155 {
156     return (!is64 ?
157             static_cast<unsigned short>(ehdr32->e_type) :
158             static_cast<unsigned short>(ehdr64->e_type));
159 }
160
161 INLINE_DEF unsigned short Elf_X::e_machine() const
162 {
163     return (!is64 ?
164             static_cast<unsigned short>(ehdr32->e_machine) :
165             static_cast<unsigned short>(ehdr64->e_machine));
166 }
167
168 INLINE_DEF unsigned long Elf_X::e_version() const
169 {
170     return (!is64 ?
171             static_cast<unsigned long>(ehdr32->e_version) :
172             static_cast<unsigned long>(ehdr64->e_version));
173 }
174
175 INLINE_DEF unsigned long Elf_X::e_entry() const
176 {
177     return (!is64 ?
178             static_cast<unsigned long>(ehdr32->e_entry) :
179             static_cast<unsigned long>(ehdr64->e_entry));
180 }
181
182 INLINE_DEF unsigned long Elf_X::e_phoff() const
183 {
184     return (!is64 ?
185             static_cast<unsigned long>(ehdr32->e_phoff) :
186             static_cast<unsigned long>(ehdr64->e_phoff));
187 }
188
189 INLINE_DEF unsigned long Elf_X::e_shoff() const
190 {
191     return (!is64 ?
192             static_cast<unsigned long>(ehdr32->e_shoff) :
193             static_cast<unsigned long>(ehdr64->e_shoff));
194 }
195
196 INLINE_DEF unsigned long Elf_X::e_flags() const
197 {
198     return (!is64 ?
199             static_cast<unsigned long>(ehdr32->e_flags) :
200             static_cast<unsigned long>(ehdr64->e_flags));
201 }
202
203 INLINE_DEF unsigned short Elf_X::e_ehsize() const
204 {
205     return (!is64 ?
206             static_cast<unsigned short>(ehdr32->e_ehsize) :
207             static_cast<unsigned short>(ehdr64->e_ehsize));
208 }
209
210 INLINE_DEF unsigned short Elf_X::e_phentsize() const {
211     return (!is64 ?
212             static_cast<unsigned short>(ehdr32->e_phentsize) :
213             static_cast<unsigned short>(ehdr64->e_phentsize));
214 }
215
216 INLINE_DEF unsigned short Elf_X::e_phnum() const
217 {
218     return (!is64 ?
219             static_cast<unsigned short>(ehdr32->e_phnum) :
220             static_cast<unsigned short>(ehdr64->e_phnum));
221 }
222
223 INLINE_DEF unsigned short Elf_X::e_shentsize() const
224 {
225     return (!is64 ?
226             static_cast<unsigned short>(ehdr32->e_shentsize) :
227             static_cast<unsigned short>(ehdr64->e_shentsize));
228 }
229
230 INLINE_DEF unsigned short Elf_X::e_shnum() const
231 {
232     return (!is64 ?
233             static_cast<unsigned short>(ehdr32->e_shnum) :
234             static_cast<unsigned short>(ehdr64->e_shnum));
235 }
236
237 INLINE_DEF unsigned short Elf_X::e_shstrndx() const
238 {
239     return (!is64 ?
240             static_cast<unsigned short>(ehdr32->e_shstrndx) :
241             static_cast<unsigned short>(ehdr64->e_shstrndx));
242 }
243
244 INLINE_DEF const char *Elf_X::e_rawfile(size_t &nbytes) const
245 {
246     return elf_rawfile(elf, &nbytes);
247 }
248
249 INLINE_DEF Elf_X *Elf_X::e_next(Elf_X *ref)
250 {
251     if (!isArchive)
252         return NULL;
253     Elf_Cmd cmd = elf_next(ref->e_elfp());
254     return new Elf_X(filedes, cmd, this);
255 }
256
257 INLINE_DEF Elf_X *Elf_X::e_rand(unsigned offset)
258 {
259     if (!isArchive)
260         return NULL;
261     elf_rand(elf, offset);
262     return new Elf_X(filedes, ELF_C_READ, this);
263 }
264
265 // Write Interface
266 INLINE_DEF void Elf_X::e_ident(unsigned char *input)
267 {
268     if (!is64) P_memcpy(ehdr32->e_ident, input, EI_NIDENT);
269     else       P_memcpy(ehdr64->e_ident, input, EI_NIDENT);
270 }
271
272 INLINE_DEF void Elf_X::e_type(unsigned short input)
273 {
274     if (!is64) ehdr32->e_type = input;
275     else       ehdr64->e_type = input;
276 }
277
278 INLINE_DEF void Elf_X::e_machine(unsigned short input)
279 {
280     if (!is64) ehdr32->e_machine = input;
281     else       ehdr64->e_machine = input;
282 }
283
284 INLINE_DEF void Elf_X::e_version(unsigned long input)
285 {
286     if (!is64) ehdr32->e_version = input;
287     else       ehdr64->e_version = input;
288 }
289
290 INLINE_DEF void Elf_X::e_entry(unsigned long input)
291 {
292     if (!is64) ehdr32->e_entry = input;
293     else       ehdr64->e_entry = input;
294 }
295
296 INLINE_DEF void Elf_X::e_phoff(unsigned long input)
297 {
298     if (!is64) ehdr32->e_phoff = input;
299     else       ehdr64->e_phoff = input;
300 }
301
302 INLINE_DEF void Elf_X::e_shoff(unsigned long input)
303 {
304     if (!is64) ehdr32->e_shoff = input;
305     else       ehdr64->e_shoff = input;
306 }
307
308 INLINE_DEF void Elf_X::e_flags(unsigned long input)
309 {
310     if (!is64) ehdr32->e_flags = input;
311     else       ehdr64->e_flags = input;
312 }
313
314 INLINE_DEF void Elf_X::e_ehsize(unsigned short input)
315 {
316     if (!is64) ehdr32->e_ehsize = input;
317     else       ehdr64->e_ehsize = input;
318 }
319
320 INLINE_DEF void Elf_X::e_phentsize(unsigned short input)
321 {
322     if (!is64) ehdr32->e_phentsize = input;
323     else       ehdr64->e_phentsize = input;
324 }
325
326 INLINE_DEF void Elf_X::e_phnum(unsigned short input)
327 {
328     if (!is64) ehdr32->e_phnum = input;
329     else       ehdr64->e_phnum = input;
330 }
331
332 INLINE_DEF void Elf_X::e_shentsize(unsigned short input)
333 {
334     if (!is64) ehdr32->e_shentsize = input;
335     else       ehdr64->e_shentsize = input;
336 }
337
338 INLINE_DEF void Elf_X::e_shnum(unsigned short input)
339 {
340     if (!is64) ehdr32->e_shnum = input;
341     else       ehdr64->e_shnum = input;
342 }
343
344 INLINE_DEF void Elf_X::e_shstrndx(unsigned short input)
345 {
346     if (!is64) ehdr32->e_shstrndx = input;
347     else       ehdr64->e_shstrndx = input;
348 }
349
350 // Data Interface
351 INLINE_DEF bool Elf_X::isValid() const
352 {
353     return (ehdr32 || ehdr64);
354 }
355
356 INLINE_DEF int Elf_X::wordSize() const
357 {
358     return (!is64 ? 4 : 8);
359 }
360
361 INLINE_DEF Elf_X_Phdr Elf_X::get_phdr(unsigned int i) const
362 {
363     if (!is64) return Elf_X_Phdr(is64, phdr32 + i);
364     else       return Elf_X_Phdr(is64, phdr64 + i);
365 }
366
367 INLINE_DEF Elf_X_Shdr Elf_X::get_shdr(unsigned int i) const
368 {
369     Elf_Scn *scn = elf_getscn(elf, i);
370     Elf_X_Shdr result(is64, scn);
371     result._elf = this;
372     return result;
373 }
374
375 // ------------------------------------------------------------------------
376 // Class Elf_X_Phdr simulates the Elf(32|64)_Phdr structure.
377 INLINE_DEF Elf_X_Phdr::Elf_X_Phdr()
378     : phdr32(NULL), phdr64(NULL), is64(false)
379 { }
380
381 INLINE_DEF Elf_X_Phdr::Elf_X_Phdr(bool is64_, void *input)
382     : phdr32(NULL), phdr64(NULL), is64(is64_)
383 {
384     if (input) {
385         if (!is64) phdr32 = (Elf32_Phdr *)input;
386         else       phdr64 = (Elf64_Phdr *)input;
387     }
388 }
389
390 // Read Interface
391 INLINE_DEF unsigned long Elf_X_Phdr::p_type() const
392 {
393     return (!is64 ?
394             static_cast<unsigned long>(phdr32->p_type) :
395             static_cast<unsigned long>(phdr64->p_type));
396 }
397
398 INLINE_DEF unsigned long Elf_X_Phdr::p_offset() const
399 {
400     return (!is64 ?
401             static_cast<unsigned long>(phdr32->p_offset) :
402             static_cast<unsigned long>(phdr64->p_offset));
403 }
404
405 INLINE_DEF unsigned long Elf_X_Phdr::p_vaddr() const
406 {
407     return (!is64 ?
408             static_cast<unsigned long>(phdr32->p_vaddr) :
409             static_cast<unsigned long>(phdr64->p_vaddr));
410 }
411
412 INLINE_DEF unsigned long Elf_X_Phdr::p_paddr() const
413 {
414     return (!is64 ?
415             static_cast<unsigned long>(phdr32->p_paddr) :
416             static_cast<unsigned long>(phdr64->p_paddr));
417 }
418
419 INLINE_DEF unsigned long Elf_X_Phdr::p_filesz() const
420 {
421     return (!is64 ?
422             static_cast<unsigned long>(phdr32->p_filesz) :
423             static_cast<unsigned long>(phdr64->p_filesz));
424 }
425
426 INLINE_DEF unsigned long Elf_X_Phdr::p_memsz() const
427 {
428     return (!is64 ?
429             static_cast<unsigned long>(phdr32->p_memsz) :
430             static_cast<unsigned long>(phdr64->p_memsz));
431 }
432
433 INLINE_DEF unsigned long Elf_X_Phdr::p_flags() const
434 {
435     return (!is64 ?
436             static_cast<unsigned long>(phdr32->p_flags) :
437             static_cast<unsigned long>(phdr64->p_flags));
438 }
439
440 INLINE_DEF unsigned long Elf_X_Phdr::p_align() const
441 {
442     return (!is64 ?
443             static_cast<unsigned long>(phdr32->p_align) :
444             static_cast<unsigned long>(phdr64->p_align));
445 }
446
447 // Write Interface
448 INLINE_DEF void Elf_X_Phdr::p_type(unsigned long input)
449 {
450     if (!is64) phdr32->p_type = input;
451     else       phdr64->p_type = input;
452 }
453
454 INLINE_DEF void Elf_X_Phdr::p_offset(unsigned long input)
455 {
456     if (!is64) phdr32->p_offset = input;
457     else       phdr64->p_offset = input;
458 }
459
460 INLINE_DEF void Elf_X_Phdr::p_vaddr(unsigned long input)
461 {
462     if (!is64) phdr32->p_vaddr = input;
463     else       phdr64->p_vaddr = input;
464 }
465
466 INLINE_DEF void Elf_X_Phdr::p_paddr(unsigned long input)
467 {
468     if (!is64) phdr32->p_paddr = input;
469     else       phdr64->p_paddr = input;
470 }
471
472 INLINE_DEF void Elf_X_Phdr::p_filesz(unsigned long input)
473 {
474     if (!is64) phdr32->p_filesz = input;
475     else       phdr64->p_filesz = input;
476 }
477
478 INLINE_DEF void Elf_X_Phdr::p_memsz(unsigned long input)
479 {
480     if (!is64) phdr32->p_memsz = input;
481     else       phdr64->p_memsz = input;
482 }
483
484 INLINE_DEF void Elf_X_Phdr::p_flags(unsigned long input)
485 {
486     if (!is64) phdr32->p_flags = input;
487     else       phdr64->p_flags = input;
488 }
489
490 INLINE_DEF void Elf_X_Phdr::p_align(unsigned long input)
491 {
492     if (!is64) phdr32->p_align = input;
493     else       phdr64->p_align = input;
494 }
495
496 INLINE_DEF bool Elf_X_Phdr::isValid() const
497 {
498     return (phdr32 || phdr64);
499 }
500
501 // ------------------------------------------------------------------------
502 // Class Elf_X_Shdr simulates the Elf(32|64)_Shdr structure.
503 INLINE_DEF Elf_X_Shdr::Elf_X_Shdr()
504     : scn(NULL), data(NULL), shdr32(NULL), shdr64(NULL), is64(false),
505       fromDebugFile(false), _elf(NULL)
506 { }
507
508 INLINE_DEF Elf_X_Shdr::Elf_X_Shdr(bool is64_, Elf_Scn *input)
509     : scn(input), data(NULL), shdr32(NULL), shdr64(NULL), is64(is64_),
510       fromDebugFile(false), _elf(NULL)
511 {
512     if (input) {
513         first_data();
514         if (!is64) shdr32 = elf32_getshdr(scn);
515         else       shdr64 = elf64_getshdr(scn);
516     }
517 }
518
519 // Read Interface
520 INLINE_DEF unsigned long Elf_X_Shdr::sh_name() const
521 {
522     return (!is64 ?
523             static_cast<unsigned long>(shdr32->sh_name) :
524             static_cast<unsigned long>(shdr64->sh_name));
525 }
526
527 INLINE_DEF unsigned long Elf_X_Shdr::sh_type() const
528 {
529     return (!is64 ?
530             static_cast<unsigned long>(shdr32->sh_type) :
531             static_cast<unsigned long>(shdr64->sh_type));
532 }
533
534 INLINE_DEF unsigned long Elf_X_Shdr::sh_flags() const
535 {
536     return (!is64 ?
537             static_cast<unsigned long>(shdr32->sh_flags) :
538             static_cast<unsigned long>(shdr64->sh_flags));
539 }
540
541 INLINE_DEF unsigned long Elf_X_Shdr::sh_addr() const
542 {
543 #if defined(os_vxworks)
544     assert(_elf);
545     if (_elf->e_type() == ET_REL) {
546         // VxWorks relocatable object files (kernel modules) don't have
547         // the address filled out.  Return the disk offset instead.
548         return (!is64 ?
549                 static_cast<unsigned long>(shdr32->sh_offset) :
550                 static_cast<unsigned long>(shdr64->sh_offset));
551     }
552 #endif
553
554     return (!is64 ?
555             static_cast<unsigned long>(shdr32->sh_addr) :
556             static_cast<unsigned long>(shdr64->sh_addr));
557 }
558
559 INLINE_DEF unsigned long Elf_X_Shdr::sh_offset() const
560 {
561     return (!is64 ?
562             static_cast<unsigned long>(shdr32->sh_offset) :
563             static_cast<unsigned long>(shdr64->sh_offset));
564 }
565
566 INLINE_DEF unsigned long Elf_X_Shdr::sh_size() const
567 {
568     return (!is64 ?
569             static_cast<unsigned long>(shdr32->sh_size) :
570             static_cast<unsigned long>(shdr64->sh_size));
571 }
572
573 INLINE_DEF unsigned long Elf_X_Shdr::sh_link() const
574 {
575     return (!is64 ?
576             shdr32->sh_link :
577             shdr64->sh_link);
578 }
579
580 INLINE_DEF unsigned long Elf_X_Shdr::sh_info() const
581 {
582     return (!is64 ?
583             static_cast<unsigned long>(shdr32->sh_info) :
584             static_cast<unsigned long>(shdr64->sh_info));
585 }
586
587 INLINE_DEF unsigned long Elf_X_Shdr::sh_addralign() const
588 {
589     return (!is64 ?
590             static_cast<unsigned long>(shdr32->sh_addralign) :
591             static_cast<unsigned long>(shdr64->sh_addralign));
592 }
593
594 INLINE_DEF unsigned long Elf_X_Shdr::sh_entsize() const
595 {
596     return (!is64 ?
597             static_cast<unsigned long>(shdr32->sh_entsize) :
598             static_cast<unsigned long>(shdr64->sh_entsize));
599 }
600
601 INLINE_DEF bool Elf_X_Shdr::isFromDebugFile() const
602 {
603     return fromDebugFile;
604 }
605
606 // Write Interface
607 INLINE_DEF void Elf_X_Shdr::sh_name(unsigned long input)
608 {
609     if (!is64) shdr32->sh_name = input;
610     else       shdr64->sh_name = input;
611 }
612
613 INLINE_DEF void Elf_X_Shdr::sh_type(unsigned long input)
614 {
615     if (!is64) shdr32->sh_type = input;
616     else       shdr64->sh_type = input;
617 }
618
619 INLINE_DEF void Elf_X_Shdr::sh_flags(unsigned long input)
620 {
621     if (!is64) shdr32->sh_flags = input;
622     else       shdr64->sh_flags = input;
623 }
624
625 INLINE_DEF void Elf_X_Shdr::sh_addr(unsigned long input)
626 {
627     if (!is64) shdr32->sh_flags = input;
628     else       shdr64->sh_flags = input;
629 }
630
631 INLINE_DEF void Elf_X_Shdr::sh_offset(unsigned long input)
632 {
633     if (!is64) shdr32->sh_offset = input;
634     else       shdr64->sh_offset = input;
635 }
636
637 INLINE_DEF void Elf_X_Shdr::sh_size(unsigned long input)
638 {
639     if (!is64) shdr32->sh_size = input;
640     else       shdr64->sh_size = input;
641 }
642
643 INLINE_DEF void Elf_X_Shdr::sh_link(unsigned long input)
644 {
645     if (!is64) shdr32->sh_link = input;
646     else       shdr64->sh_link = input;
647 }
648
649 INLINE_DEF void Elf_X_Shdr::sh_info(unsigned long input)
650 {
651     if (!is64) shdr32->sh_info = input;
652     else       shdr64->sh_info = input;
653 }
654
655 INLINE_DEF void Elf_X_Shdr::sh_addralign(unsigned long input)
656 {
657     if (!is64) shdr32->sh_addralign = input;
658     else       shdr64->sh_addralign = input;
659 }
660
661 INLINE_DEF void Elf_X_Shdr::sh_entsize(unsigned long input)
662 {
663     if (!is64) shdr32->sh_entsize = input;
664     else       shdr64->sh_entsize = input;
665 }
666
667 INLINE_DEF void Elf_X_Shdr::setDebugFile(bool b)
668 {
669     fromDebugFile = b;
670 }
671
672 // Section Data Interface
673 INLINE_DEF Elf_X_Data Elf_X_Shdr::get_data() const
674 {
675     return Elf_X_Data(is64, data);
676 }
677
678 // For Sections with Multiple Data Sections
679 INLINE_DEF void Elf_X_Shdr::first_data()
680 {
681     data = elf_getdata(scn, NULL);
682 }
683
684 INLINE_DEF bool Elf_X_Shdr::next_data()
685 {
686     Elf_Data *nextData = elf_getdata(scn, data);
687     if (nextData) data = nextData;
688     return nextData;
689 }
690
691 INLINE_DEF bool Elf_X_Shdr::isValid() const
692 {
693     return (shdr32 || shdr64);
694 }
695
696 INLINE_DEF unsigned Elf_X_Shdr::wordSize() const
697 {
698     return is64 ? 8 : 4;
699 }
700
701 INLINE_DEF Elf_Scn *Elf_X_Shdr::getScn() const
702 {
703     return scn;
704 }
705
706 // ------------------------------------------------------------------------
707 // Class Elf_X_Data simulates the Elf_Data structure.
708 INLINE_DEF Elf_X_Data::Elf_X_Data()
709     : data(NULL), is64(false)
710 { }
711
712 INLINE_DEF Elf_X_Data::Elf_X_Data(bool is64_, Elf_Data *input)
713     : data(input), is64(is64_)
714 { }
715
716 // Read Interface
717 INLINE_DEF void *Elf_X_Data::d_buf() const
718 {
719     return data->d_buf;
720 }
721
722 INLINE_DEF Elf_Type Elf_X_Data::d_type() const
723 {
724     return data->d_type;
725 }
726
727 INLINE_DEF unsigned int Elf_X_Data::d_version() const
728 {
729     return data->d_version;
730 }
731
732 INLINE_DEF size_t Elf_X_Data::d_size() const
733 {
734     return data->d_size;
735 }
736
737 INLINE_DEF off_t Elf_X_Data::d_off() const
738 {
739     return (off_t) data->d_off;
740 }
741
742 INLINE_DEF size_t Elf_X_Data::d_align() const
743 {
744     return data->d_align;
745 }
746
747 // Write Interface
748 INLINE_DEF void Elf_X_Data::d_buf(void *input)
749 {
750     data->d_buf = input;
751 }
752
753 INLINE_DEF void Elf_X_Data::d_type(Elf_Type input)
754 {
755     data->d_type = input;
756 }
757
758 INLINE_DEF void Elf_X_Data::d_version(unsigned int input)
759 {
760     data->d_version = input;
761 }
762
763 INLINE_DEF void Elf_X_Data::d_size(unsigned int input)
764 {
765     data->d_size = input;
766 }
767
768 INLINE_DEF void Elf_X_Data::d_off(signed int input)
769 {
770     data->d_off = input;
771 }
772
773 INLINE_DEF void Elf_X_Data::d_align(unsigned int input)
774 {
775     data->d_align = input;
776 }
777
778 // Data Interface
779 INLINE_DEF const char *Elf_X_Data::get_string() const
780 {
781     return (const char *)data->d_buf;
782 }
783
784 INLINE_DEF Elf_X_Dyn Elf_X_Data::get_dyn()
785 {
786     return Elf_X_Dyn(is64, data);
787 }
788
789 INLINE_DEF Elf_X_Versym Elf_X_Data::get_versyms()
790 {
791     return Elf_X_Versym(is64, data);
792 }
793
794 INLINE_DEF Elf_X_Verneed *Elf_X_Data::get_verNeedSym()
795 {
796     return new Elf_X_Verneed(is64, data->d_buf);
797 }
798
799 INLINE_DEF Elf_X_Verdef *Elf_X_Data::get_verDefSym()
800 {
801     return new Elf_X_Verdef(is64, data->d_buf);
802 }
803
804 INLINE_DEF Elf_X_Rel Elf_X_Data::get_rel()
805 {
806     return Elf_X_Rel(is64, data);
807 }
808
809 INLINE_DEF Elf_X_Rela Elf_X_Data::get_rela()
810 {
811     return Elf_X_Rela(is64, data);
812 }
813
814 INLINE_DEF Elf_X_Sym Elf_X_Data::get_sym()
815 {
816     return Elf_X_Sym(is64, data);
817 }
818
819 #if defined(arch_mips)
820 INLINE_DEF Elf_X_Options Elf_X_Data::get_options()
821 {
822     return Elf_X_Options(is64, data);
823 }
824 #endif
825
826 INLINE_DEF bool Elf_X_Data::isValid() const
827 {
828     return data;
829 }
830
831 // ------------------------------------------------------------------------
832 // Class Elf_X_Versym simulates the SHT_GNU_versym structure.
833 INLINE_DEF Elf_X_Versym::Elf_X_Versym()
834     : data(NULL), versym32(NULL), versym64(NULL), is64(false)
835 { }
836
837 INLINE_DEF Elf_X_Versym::Elf_X_Versym(bool is64_, Elf_Data *input)
838     : data(input), versym32(NULL), versym64(NULL), is64(is64_)
839 {
840     if (input) {
841         if (!is64) versym32 = (Elf32_Half *)data->d_buf;
842         else       versym64 = (Elf64_Half *)data->d_buf;
843     }
844 }
845
846 // Read Interface
847 INLINE_DEF unsigned long Elf_X_Versym::get(int i) const
848 {
849     return (!is64 ? versym32[i]
850                   : versym64[i]);
851 }
852
853 // Meta-Info Interface
854 INLINE_DEF unsigned long Elf_X_Versym::count() const
855 {
856     return (data->d_size / (!is64 ? sizeof(Elf32_Half)
857                                   : sizeof(Elf64_Half) ));
858 }
859
860 INLINE_DEF bool Elf_X_Versym::isValid() const
861 {
862     return (versym32 || versym64);
863 }
864
865 // ------------------------------------------------------------------------
866 // Class Elf_X_Verdaux simulates the Elf(32|64)_Verdaux structure.
867 INLINE_DEF Elf_X_Verdaux::Elf_X_Verdaux()
868     : data(NULL), verdaux32(NULL), verdaux64(NULL), is64(false)
869 { }
870
871 INLINE_DEF Elf_X_Verdaux::Elf_X_Verdaux(bool is64_, void *input)
872     : data(input), verdaux32(NULL), verdaux64(NULL), is64(is64_)
873 {
874     if (input) {
875         if (!is64) verdaux32 = (Elf32_Verdaux *)data;
876         else       verdaux64 = (Elf64_Verdaux *)data;
877     }
878 }
879
880 // Read Interface
881 INLINE_DEF unsigned long Elf_X_Verdaux::vda_name() const
882 {
883     return (!is64 ? verdaux32->vda_name
884                   : verdaux64->vda_name);
885 }
886
887 INLINE_DEF unsigned long Elf_X_Verdaux::vda_next() const
888 {
889     return (!is64 ? verdaux32->vda_next
890                   : verdaux64->vda_next);
891 }
892
893 INLINE_DEF Elf_X_Verdaux *Elf_X_Verdaux::get_next() const
894 {
895     if (vda_next() == 0)
896         return NULL;
897     return new Elf_X_Verdaux(is64, (char *)data+vda_next());
898 }
899
900 // Meta-Info Interface
901 INLINE_DEF bool Elf_X_Verdaux::isValid() const
902 {
903     return (verdaux32 || verdaux64);
904 }
905
906 // ------------------------------------------------------------------------
907 // Class Elf_X_Verdef simulates the Elf(32|64)_Verdef structure.
908 INLINE_DEF Elf_X_Verdef::Elf_X_Verdef()
909     : data(NULL), verdef32(NULL), verdef64(NULL), is64(false)
910 { }
911
912 INLINE_DEF Elf_X_Verdef::Elf_X_Verdef(bool is64_, void *input)
913     : data(input), verdef32(NULL), verdef64(NULL), is64(is64_)
914 {
915     if (input) {
916         if (!is64) verdef32 = (Elf32_Verdef *)data;
917         else       verdef64 = (Elf64_Verdef *)data;
918     }
919 }
920
921 // Read Interface
922 INLINE_DEF unsigned long Elf_X_Verdef::vd_version() const
923 {
924     return (!is64 ? verdef32->vd_version
925                   : verdef64->vd_version);
926 }
927
928 INLINE_DEF unsigned long Elf_X_Verdef::vd_flags() const
929 {
930     return (!is64 ? verdef32->vd_flags
931                   : verdef64->vd_flags);
932 }
933
934 INLINE_DEF unsigned long Elf_X_Verdef::vd_ndx() const
935 {
936     return (!is64 ? verdef32->vd_ndx
937                   : verdef64->vd_ndx);
938 }
939
940 INLINE_DEF unsigned long Elf_X_Verdef::vd_cnt() const
941 {
942     return (!is64 ? verdef32->vd_cnt
943                   : verdef64->vd_cnt);
944 }
945
946 INLINE_DEF unsigned long Elf_X_Verdef::vd_hash() const
947 {
948     return (!is64 ? verdef32->vd_hash
949                   : verdef64->vd_hash);
950 }
951
952 INLINE_DEF unsigned long Elf_X_Verdef::vd_aux() const
953 {
954     return (!is64 ? verdef32->vd_aux
955                   : verdef64->vd_aux);
956 }
957
958 INLINE_DEF unsigned long Elf_X_Verdef::vd_next() const
959 {
960     return (!is64 ? verdef32->vd_next
961                   : verdef64->vd_next);
962 }
963
964 INLINE_DEF Elf_X_Verdaux *Elf_X_Verdef::get_aux() const
965 {
966     if (vd_cnt() == 0)
967         return NULL;
968     return new Elf_X_Verdaux(is64, (char *)data+vd_aux());
969 }
970
971 INLINE_DEF Elf_X_Verdef *Elf_X_Verdef::get_next() const
972 {
973     if (vd_next() == 0)
974         return NULL;
975     return new Elf_X_Verdef(is64, (char *)data+vd_next());
976 }
977
978 // Meta-Info Interface
979 INLINE_DEF bool Elf_X_Verdef::isValid() const
980 {
981     return (verdef32 || verdef64);
982 }
983
984 // ------------------------------------------------------------------------
985 // Class Elf_X_Vernaux simulates the Elf(32|64)_Vernaux structure.
986 INLINE_DEF Elf_X_Vernaux::Elf_X_Vernaux()
987     : data(NULL), vernaux32(NULL), vernaux64(NULL), is64(false)
988 { }
989
990 INLINE_DEF Elf_X_Vernaux::Elf_X_Vernaux(bool is64_, void *input)
991     : data(input), vernaux32(NULL), vernaux64(NULL), is64(is64_)
992 {
993     if (input) {
994         if (!is64) vernaux32 = (Elf32_Vernaux *)data;
995         else       vernaux64 = (Elf64_Vernaux *)data;
996     }
997 }
998
999 // Read Interface
1000 INLINE_DEF unsigned long Elf_X_Vernaux::vna_hash() const
1001 {
1002     return (!is64 ? vernaux32->vna_hash
1003                   : vernaux64->vna_hash);
1004 }
1005
1006 INLINE_DEF unsigned long Elf_X_Vernaux::vna_flags() const
1007 {
1008     return (!is64 ? vernaux32->vna_flags
1009                   : vernaux64->vna_flags);
1010 }
1011
1012 INLINE_DEF unsigned long Elf_X_Vernaux::vna_other() const
1013 {
1014     return (!is64 ? vernaux32->vna_other
1015                   : vernaux64->vna_other);
1016 }
1017
1018 INLINE_DEF unsigned long Elf_X_Vernaux::vna_name() const
1019 {
1020     return (!is64 ? vernaux32->vna_name
1021                   : vernaux64->vna_name);
1022 }
1023
1024 INLINE_DEF unsigned long Elf_X_Vernaux::vna_next() const
1025 {
1026     return (!is64 ? vernaux32->vna_next
1027                   : vernaux64->vna_next);
1028 }
1029
1030 INLINE_DEF Elf_X_Vernaux *Elf_X_Vernaux::get_next() const
1031 {
1032     if (vna_next() == 0)
1033         return NULL;
1034     return new Elf_X_Vernaux(is64, (char *)data+vna_next());
1035 }
1036
1037 // Meta-Info Interface
1038 INLINE_DEF bool Elf_X_Vernaux::isValid() const
1039 {
1040     return (vernaux32 || vernaux64);
1041 }
1042
1043 // ------------------------------------------------------------------------
1044 // Class Elf_X_Verneed simulates the Elf(32|64)_Verneed structure.
1045 INLINE_DEF Elf_X_Verneed::Elf_X_Verneed()
1046     : data(NULL), verneed32(NULL), verneed64(NULL), is64(false)
1047 { }
1048
1049 INLINE_DEF Elf_X_Verneed::Elf_X_Verneed(bool is64_, void *input)
1050     : data(input), verneed32(NULL), verneed64(NULL), is64(is64_)
1051 {
1052     if (input) {
1053         if (!is64) verneed32 = (Elf32_Verneed *)data;
1054         else       verneed64 = (Elf64_Verneed *)data;
1055     }
1056 }
1057
1058 // Read Interface
1059 INLINE_DEF unsigned long Elf_X_Verneed::vn_version() const
1060 {
1061     return (!is64 ? verneed32->vn_version
1062                   : verneed64->vn_version);
1063 }
1064
1065 INLINE_DEF unsigned long Elf_X_Verneed::vn_cnt() const
1066 {
1067     return (!is64 ? verneed32->vn_cnt
1068             : verneed64->vn_cnt);
1069 }
1070
1071 INLINE_DEF unsigned long Elf_X_Verneed::vn_file() const
1072 {
1073     return (!is64 ? verneed32->vn_file
1074                   : verneed64->vn_file);
1075 }
1076
1077 INLINE_DEF unsigned long Elf_X_Verneed::vn_aux() const
1078 {
1079     return (!is64 ? verneed32->vn_aux
1080                   : verneed64->vn_aux);
1081 }
1082
1083 INLINE_DEF unsigned long Elf_X_Verneed::vn_next() const
1084 {
1085     return (!is64 ? verneed32->vn_next
1086             : verneed64->vn_next);
1087 }
1088
1089 INLINE_DEF Elf_X_Vernaux *Elf_X_Verneed::get_aux() const
1090 {
1091     if (vn_cnt() == 0)
1092         return NULL;
1093     return new Elf_X_Vernaux(is64, (char *)data+vn_aux());
1094 }
1095
1096 INLINE_DEF Elf_X_Verneed *Elf_X_Verneed::get_next() const
1097 {
1098     if (vn_next() == 0)
1099         return NULL;
1100     return new Elf_X_Verneed(is64, (char *)data+vn_next());
1101 }
1102
1103 // Meta-Info Interface
1104 INLINE_DEF bool Elf_X_Verneed::isValid() const
1105 {
1106     return (verneed32 || verneed64);
1107 }
1108
1109
1110 // ------------------------------------------------------------------------
1111 // Class Elf_X_Sym simulates the Elf(32|64)_Sym structure.
1112 INLINE_DEF Elf_X_Sym::Elf_X_Sym()
1113     : data(NULL), sym32(NULL), sym64(NULL), is64(false)
1114 { }
1115
1116 INLINE_DEF Elf_X_Sym::Elf_X_Sym(bool is64_, Elf_Data *input)
1117     : data(input), sym32(NULL), sym64(NULL), is64(is64_)
1118 {
1119     if (input) {
1120         if (!is64) sym32 = (Elf32_Sym *)data->d_buf;
1121         else       sym64 = (Elf64_Sym *)data->d_buf;
1122     }
1123 }
1124
1125 // Read Interface
1126 INLINE_DEF unsigned long Elf_X_Sym::st_name(int i) const
1127 {
1128     return (!is64 ?
1129             static_cast<unsigned long>(sym32[i].st_name) :
1130             static_cast<unsigned long>(sym64[i].st_name));
1131 }
1132
1133 INLINE_DEF unsigned long Elf_X_Sym::st_value(int i) const
1134 {
1135     return (!is64 ?
1136             static_cast<unsigned long>(sym32[i].st_value) :
1137             static_cast<unsigned long>(sym64[i].st_value));
1138 }
1139
1140 INLINE_DEF unsigned long Elf_X_Sym::st_size(int i) const
1141 {
1142     return (!is64 ?
1143             static_cast<unsigned long>(sym32[i].st_size) :
1144             static_cast<unsigned long>(sym64[i].st_size));
1145 }
1146
1147 INLINE_DEF unsigned char Elf_X_Sym::st_info(int i) const
1148 {
1149     return (!is64 ?
1150             sym32[i].st_info :
1151             sym64[i].st_info);
1152 }
1153
1154 INLINE_DEF unsigned char Elf_X_Sym::st_other(int i) const
1155 {
1156     return (!is64 ?
1157             sym32[i].st_other :
1158             sym64[i].st_other);
1159 }
1160
1161 INLINE_DEF unsigned short Elf_X_Sym::st_shndx(int i) const
1162 {
1163     return (!is64 ?
1164             sym32[i].st_shndx :
1165             sym64[i].st_shndx);
1166 }
1167
1168 INLINE_DEF unsigned char Elf_X_Sym::ST_BIND(int i) const
1169 {
1170     return (!is64 ?
1171             static_cast<unsigned char>(ELF32_ST_BIND(sym32[i].st_info)) :
1172             static_cast<unsigned char>(ELF64_ST_BIND(sym64[i].st_info)));
1173 }
1174
1175 INLINE_DEF unsigned char Elf_X_Sym::ST_TYPE(int i) const
1176 {
1177     return (!is64 ?
1178             static_cast<unsigned char>(ELF32_ST_TYPE(sym32[i].st_info)) :
1179             static_cast<unsigned char>(ELF64_ST_TYPE(sym64[i].st_info)));
1180 }
1181
1182 INLINE_DEF unsigned char Elf_X_Sym::ST_VISIBILITY(int i) const
1183 {
1184     return (!is64 ?
1185             static_cast<unsigned char>(ELF32_ST_VISIBILITY(sym32[i].st_other)) :
1186             static_cast<unsigned char>(ELF64_ST_VISIBILITY(sym64[i].st_other)));
1187 }
1188
1189 INLINE_DEF void *Elf_X_Sym::st_symptr(int i) const
1190 {
1191     return (!is64 ?
1192             (void *)(sym32 + i) :
1193             (void *)(sym64 + i));
1194 }
1195
1196 INLINE_DEF unsigned Elf_X_Sym::st_entsize() const
1197 {
1198     return (is64 ?
1199             sizeof(Elf64_Sym) :
1200             sizeof(Elf32_Sym));
1201 }
1202
1203 // Write Interface
1204 INLINE_DEF void Elf_X_Sym::st_name(int i, unsigned long input)
1205 {
1206     if (!is64) sym32[i].st_name = input;
1207     else       sym64[i].st_name = input;
1208 }
1209
1210 INLINE_DEF void Elf_X_Sym::st_value(int i, unsigned long input)
1211 {
1212     if (!is64) sym32[i].st_value = input;
1213     else       sym64[i].st_value = input;
1214 }
1215
1216 INLINE_DEF void Elf_X_Sym::st_size(int i, unsigned long input)
1217 {
1218     if (!is64) sym32[i].st_size = input;
1219     else       sym64[i].st_size = input;
1220 }
1221
1222 INLINE_DEF void Elf_X_Sym::st_info(int i, unsigned char input)
1223 {
1224     if (!is64) sym32[i].st_info = input;
1225     else       sym64[i].st_info = input;
1226 }
1227
1228 INLINE_DEF void Elf_X_Sym::st_other(int i, unsigned char input)
1229 {
1230     if (!is64) sym32[i].st_other = input;
1231     else       sym64[i].st_other = input;
1232 }
1233
1234 INLINE_DEF void Elf_X_Sym::st_shndx(int i, unsigned short input)
1235 {
1236     if (!is64) sym32[i].st_shndx = input;
1237     else       sym64[i].st_shndx = input;
1238 }
1239
1240 // Meta-Info Interface
1241 INLINE_DEF unsigned long Elf_X_Sym::count() const
1242 {
1243     return (data->d_size / (!is64 ? sizeof(Elf32_Sym)
1244                                   : sizeof(Elf64_Sym)));
1245 }
1246
1247 INLINE_DEF bool Elf_X_Sym::isValid() const
1248 {
1249     return sym32 || sym64;
1250 }
1251
1252 // ------------------------------------------------------------------------
1253 // Class Elf_X_Rel simulates the Elf(32|64)_Rel structure.
1254 INLINE_DEF Elf_X_Rel::Elf_X_Rel()
1255     : data(NULL), rel32(NULL), rel64(NULL), is64(false)
1256 { }
1257
1258 INLINE_DEF Elf_X_Rel::Elf_X_Rel(bool is64_, Elf_Data *input)
1259     : data(input), rel32(NULL), rel64(NULL), is64(is64_)
1260 {
1261     if (input) {
1262         if (!is64) 
1263             rel32 = (Elf32_Rel *)data->d_buf;
1264         else       
1265             rel64 = (Elf64_Rel *)data->d_buf;
1266     }
1267 }
1268
1269 // Read Interface
1270 INLINE_DEF unsigned long Elf_X_Rel::r_offset(int i) const
1271 {
1272     return (!is64 ?
1273             static_cast<unsigned long>(rel32[i].r_offset) :
1274             static_cast<unsigned long>(rel64[i].r_offset));
1275 }
1276
1277 INLINE_DEF unsigned long Elf_X_Rel::r_info(int i) const
1278 {
1279     return (!is64 ?
1280             static_cast<unsigned long>(rel32[i].r_info) :
1281             static_cast<unsigned long>(rel64[i].r_info));
1282 }
1283
1284 INLINE_DEF unsigned long Elf_X_Rel::R_SYM(int i) const
1285 {
1286     return (!is64 ?
1287             static_cast<unsigned long>(ELF32_R_SYM(rel32[i].r_info)) :
1288             static_cast<unsigned long>(ELF64_R_SYM(rel64[i].r_info)));
1289 }
1290
1291 INLINE_DEF unsigned long Elf_X_Rel::R_TYPE(int i) const
1292 {
1293     return (!is64 ?
1294             static_cast<unsigned long>(ELF32_R_TYPE(rel32[i].r_info)) :
1295             static_cast<unsigned long>(ELF64_R_TYPE(rel64[i].r_info)));
1296 };
1297
1298 // Write Interface
1299 INLINE_DEF void Elf_X_Rel::r_offset(int i, unsigned long input)
1300 {
1301     if (!is64)
1302         rel32[i].r_offset = input;
1303     else
1304         rel64[i].r_offset = input;
1305 }
1306
1307 INLINE_DEF void Elf_X_Rel::r_info(int i, unsigned long input)
1308 {
1309     if (!is64)
1310         rel32[i].r_info = input;
1311     else
1312         rel64[i].r_info = input;
1313 }
1314
1315 // Meta-Info Interface
1316 INLINE_DEF unsigned long Elf_X_Rel::count() const
1317 {
1318     return (data->d_size / (!is64 ? sizeof(Elf32_Rel)
1319                                   : sizeof(Elf64_Rel)) );
1320 }
1321
1322 INLINE_DEF bool Elf_X_Rel::isValid() const
1323 {
1324     return (rel32 || rel64);
1325 }
1326
1327 // ------------------------------------------------------------------------
1328 // Class Elf_X_Rela simulates the Elf(32|64)_Rela structure.
1329 INLINE_DEF Elf_X_Rela::Elf_X_Rela()
1330     : data(NULL), rela32(NULL), rela64(NULL), is64(false)
1331 { }
1332
1333 INLINE_DEF Elf_X_Rela::Elf_X_Rela(bool is64_, Elf_Data *input)
1334     : data(input), rela32(NULL), rela64(NULL), is64(is64_)
1335 {
1336     if (input) {
1337         if (!is64) 
1338             rela32 = (Elf32_Rela *)data->d_buf;
1339         else       
1340             rela64 = (Elf64_Rela *)data->d_buf;
1341     }
1342 }
1343
1344 // Read Interface
1345 INLINE_DEF unsigned long Elf_X_Rela::r_offset(int i) const
1346 {
1347     return (!is64 ?
1348             static_cast<unsigned long>(rela32[i].r_offset) :
1349             static_cast<unsigned long>(rela64[i].r_offset));
1350 }
1351
1352 INLINE_DEF unsigned long Elf_X_Rela::r_info(int i) const
1353 {
1354     return (!is64 ?
1355             static_cast<unsigned long>(rela32[i].r_info) :
1356             static_cast<unsigned long>(rela64[i].r_info));
1357 }
1358
1359 INLINE_DEF signed long Elf_X_Rela::r_addend(int i) const
1360 {
1361     return (!is64 ?
1362             static_cast<signed long>(rela32[i].r_addend) :
1363             static_cast<signed long>(rela64[i].r_addend));
1364 }
1365
1366 INLINE_DEF unsigned long Elf_X_Rela::R_SYM(int i) const
1367 {
1368     return (!is64 ?
1369             static_cast<unsigned long>(ELF32_R_SYM(rela32[i].r_info)) :
1370             static_cast<unsigned long>(ELF64_R_SYM(rela64[i].r_info)));
1371 }
1372
1373 INLINE_DEF unsigned long Elf_X_Rela::R_TYPE(int i) const
1374 {
1375     return (!is64 ?
1376             static_cast<unsigned long>(ELF32_R_TYPE(rela32[i].r_info)) :
1377             static_cast<unsigned long>(ELF64_R_TYPE(rela64[i].r_info)));
1378 }
1379
1380 // Write Interface
1381 INLINE_DEF void Elf_X_Rela::r_offset(int i, unsigned long input)
1382 {
1383     if (!is64)
1384         rela32[i].r_offset = input;
1385     else
1386         rela64[i].r_offset = input;
1387 }
1388
1389 INLINE_DEF void Elf_X_Rela::r_info(int i, unsigned long input)
1390 {
1391     if (!is64)
1392         rela32[i].r_info = input;
1393     else
1394         rela64[i].r_info = input;
1395 }
1396
1397 INLINE_DEF void Elf_X_Rela::r_addend(int i, signed long input)
1398 {
1399     if (!is64)
1400         rela32[i].r_addend = input;
1401     else
1402         rela64[i].r_addend = input;
1403 }
1404
1405 // Meta-Info Interface
1406 INLINE_DEF unsigned long Elf_X_Rela::count() const
1407 {
1408     return (data->d_size / (!is64 ? sizeof(Elf32_Rela)
1409                                   : sizeof(Elf64_Rela)));
1410 }
1411
1412 INLINE_DEF bool Elf_X_Rela::isValid() const
1413 {
1414     return (rela32 || rela64);
1415 }
1416
1417
1418 // ------------------------------------------------------------------------
1419 // Class Elf_X_Dyn simulates the Elf(32|64)_Dyn structure.
1420 INLINE_DEF Elf_X_Dyn::Elf_X_Dyn()
1421     : data(NULL), dyn32(NULL), dyn64(NULL), is64(false)
1422 { }
1423
1424 INLINE_DEF Elf_X_Dyn::Elf_X_Dyn(bool is64_, Elf_Data *input)
1425     : data(input), dyn32(NULL), dyn64(NULL), is64(is64_)
1426 {
1427     if (input) {
1428         if (!is64) dyn32 = (Elf32_Dyn *)data->d_buf;
1429         else       dyn64 = (Elf64_Dyn *)data->d_buf;
1430     }
1431 }
1432
1433 // Read Interface
1434 INLINE_DEF signed long Elf_X_Dyn::d_tag(int i) const
1435
1436     return (!is64 ?
1437             static_cast<signed long>(dyn32[i].d_tag) :
1438             static_cast<signed long>(dyn64[i].d_tag));
1439 }
1440
1441 INLINE_DEF unsigned long Elf_X_Dyn::d_val(int i) const
1442 {
1443     return (!is64 ?
1444             static_cast<unsigned long>(dyn32[i].d_un.d_val) :
1445             static_cast<unsigned long>(dyn64[i].d_un.d_val));
1446 }
1447
1448 INLINE_DEF unsigned long Elf_X_Dyn::d_ptr(int i) const
1449 {
1450     return (!is64 ?
1451             static_cast<unsigned long>(dyn32[i].d_un.d_ptr) :
1452             static_cast<unsigned long>(dyn64[i].d_un.d_ptr));
1453 }
1454
1455 // Write Interface
1456 INLINE_DEF void Elf_X_Dyn::d_tag(int i, signed long input)
1457 {
1458     if (!is64) dyn32[i].d_tag = input;
1459     else       dyn64[i].d_tag = input;
1460 }
1461
1462 INLINE_DEF void Elf_X_Dyn::d_val(int i, unsigned long input)
1463 {
1464     if (!is64) dyn32[i].d_un.d_val = input;
1465     else       dyn64[i].d_un.d_val = input;
1466 }
1467
1468 INLINE_DEF void Elf_X_Dyn::d_ptr(int i, unsigned long input)
1469 {
1470     if (!is64) dyn32[i].d_un.d_ptr = input;
1471     else       dyn64[i].d_un.d_ptr = input;
1472 }
1473
1474 // Meta-Info Interface
1475 INLINE_DEF unsigned long Elf_X_Dyn::count() const
1476 {
1477     return (data->d_size / (!is64 ? sizeof(Elf32_Dyn)
1478                                   : sizeof(Elf64_Dyn) ));
1479 }
1480
1481 INLINE_DEF bool Elf_X_Dyn::isValid() const
1482 {
1483     return (dyn32 || dyn64);
1484 }
1485
1486 static bool loadDebugFileFromDisk(string name, char* &output_buffer, unsigned long &output_buffer_size)
1487 {
1488    struct stat fileStat;
1489    int result = stat(name.c_str(), &fileStat);
1490    if (result == -1)
1491       return false;
1492    int fd = open(name.c_str(), O_RDONLY);
1493    if (fd == -1)
1494       return false;
1495
1496    char *buffer = (char *) mmap(NULL, fileStat.st_size, PROT_READ, MAP_SHARED, fd, 0);
1497    close(fd);
1498    if (!buffer)
1499       return false;
1500
1501    output_buffer = buffer;
1502    output_buffer_size = fileStat.st_size;
1503
1504    return true;
1505 }
1506
1507 // The standard procedure to look for a separate debug information file
1508 // is as follows:
1509 // 1. Lookup build_id from .note.gnu.build-id section and debug-file-name and
1510 //    crc from .gnu_debuglink section of the original binary.
1511 // 2. Look for the following files:
1512 //        /usr/lib/debug/.build-id/<path-obtained-using-build-id>.debug
1513 //        <debug-file-name> in <directory-of-executable>
1514 //        <debug-file-name> in <directory-of-executable>/.debug
1515 //        <debug-file-name> in /usr/lib/debug/<directory-of-executable>
1516 // Reference: http://sourceware.org/gdb/current/onlinedocs/gdb_16.html#SEC157
1517 INLINE_DEF bool Elf_X::findDebugFile(std::string origfilename, string &output_name, char* &output_buffer, unsigned long &output_buffer_size)
1518 {
1519    uint16_t shnames_idx = e_shstrndx();
1520    Elf_X_Shdr shnames_hdr = get_shdr(shnames_idx);
1521    if (!shnames_hdr.isValid())
1522       return false;
1523    const char *shnames = (const char *) shnames_hdr.get_data().d_buf();
1524    
1525   string debugFileFromDebugLink, debugFileFromBuildID;
1526   unsigned debugFileCrc = 0;
1527
1528   for(int i = 0; i < e_shnum(); i++) {
1529      Elf_X_Shdr scn = get_shdr(i);
1530      if (!scn.isValid()) { // section is malformed
1531         continue;
1532      }
1533
1534      const char *name = &shnames[scn.sh_name()];
1535      if(strcmp(name, DEBUGLINK_NAME) == 0) {
1536         Elf_X_Data data = scn.get_data();
1537         debugFileFromDebugLink = (char *) data.d_buf();
1538         void *crcLocation = ((char *) data.d_buf() + data.d_size() - 4);
1539         debugFileCrc = *(unsigned *) crcLocation;
1540      }
1541      else if(strcmp(name, BUILD_ID_NAME) == 0) {
1542         char *buildId = (char *) scn.get_data().d_buf();
1543         string filename = string(buildId + 2) + ".debug";
1544         string subdir = string(buildId, 2);
1545         debugFileFromBuildID = "/usr/lib/debug/.build-id/" + subdir + "/" + filename;
1546      }
1547   }
1548
1549   if (!debugFileFromBuildID.empty()) {
1550      bool result = loadDebugFileFromDisk(debugFileFromBuildID, output_buffer, output_buffer_size);
1551      if (result) {
1552         output_name = debugFileFromBuildID;
1553         return true;
1554      }
1555   }
1556
1557   if (debugFileFromDebugLink.empty())
1558      return false;
1559
1560   char *mfPathNameCopy = strdup(origfilename.c_str());
1561   string objectFileDirName = dirname(mfPathNameCopy);
1562
1563   vector<string> fnames = list_of
1564     (objectFileDirName + "/" + debugFileFromDebugLink)
1565     (objectFileDirName + "/.debug/" + debugFileFromDebugLink)
1566     ("/usr/lib/debug/" + objectFileDirName + "/" + debugFileFromDebugLink);
1567
1568   free(mfPathNameCopy);
1569
1570   for(unsigned i = 0; i < fnames.size(); i++) {
1571      bool result = loadDebugFileFromDisk(fnames[i], output_buffer, output_buffer_size);
1572      if (!result)
1573         continue;
1574     
1575     boost::crc_32_type crcComputer;
1576     crcComputer.process_bytes(output_buffer, output_buffer_size);
1577     if(crcComputer.checksum() != debugFileCrc) {
1578        munmap(output_buffer, output_buffer_size);
1579        continue;
1580     }
1581
1582     output_name = fnames[i];
1583     return true;
1584   }
1585
1586   return false;
1587 }