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