Determine the architecture of an ELF by looking at the file header instead of the...
[dyninst.git] / elf / h / Elf_X.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  * 
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  * 
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  * 
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  * 
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #ifndef __ELF_X_H__
32 #define __ELF_X_H__
33
34 #include "libelf.h"
35 #include <string>
36 #include <map>
37 #include <vector>
38 #include "util.h"
39 #include "dyn_regs.h"
40
41 namespace Dyninst {
42
43 // Forward declarations
44 class Elf_X;
45 class Elf_X_Phdr;
46 class Elf_X_Shdr;
47 class Elf_X_Data;
48 class Elf_X_Versym;
49 class Elf_X_Verdaux;
50 class Elf_X_Verdef;
51 class Elf_X_Vernaux;
52 class Elf_X_Verneed;
53 class Elf_X_Options;
54 class Elf_X_Sym;
55 class Elf_X_Rel;
56 class Elf_X_Rela;
57 class Elf_X_RegInfo;
58 class Elf_32_RegInfo;
59 class Elf_64_RegInfo;
60 class Elf_X_Dyn;
61 class Elf_X_Nhdr;
62
63
64 // Wrappers to allow word-independant use of libelf routines.
65
66 // ------------------------------------------------------------------------
67 // Class Elf_X simulates the Elf(32|64)_Ehdr structure.
68 // Also works for ELF archives. 
69 class DYNELF_EXPORT Elf_X {
70   public:
71     static Elf_X *newElf_X(int input, Elf_Cmd cmd, Elf_X *ref = NULL, std::string name = std::string());
72     static Elf_X *newElf_X(char *mem_image, size_t mem_size, std::string name = std::string());
73     void end();
74
75     // Read Interface
76     Elf *e_elfp() const;
77     unsigned char *e_ident() const;
78     unsigned short e_type() const;
79     unsigned short e_machine() const;
80     unsigned long e_version() const;
81     unsigned long e_entry() const;
82     unsigned long e_phoff() const;
83     unsigned long e_shoff() const;
84     unsigned long e_flags() const;
85     unsigned short e_ehsize() const;
86     unsigned short e_phentsize() const;
87     unsigned short e_phnum() const;
88     unsigned short e_shentsize() const;
89     unsigned short e_shnum() const;
90     unsigned short e_shstrndx() const;
91     const char *e_rawfile(size_t &nbytes) const;
92     unsigned short e_endian() const;
93
94     Elf_X *e_next(Elf_X *ref);
95     Elf_X *e_rand(unsigned offset);
96
97     // Write Interface
98     void e_ident(unsigned char *input);
99     void e_type(unsigned short input);
100     void e_machine(unsigned short input);
101     void e_version(unsigned long input);
102     void e_entry(unsigned long input);
103     void e_phoff(unsigned long input);
104     void e_shoff(unsigned long input);
105     void e_flags(unsigned long input);
106     void e_ehsize(unsigned short input);
107     void e_phentsize(unsigned short input);
108     void e_phnum(unsigned short input);
109     void e_shentsize(unsigned short input);
110     void e_shnum(unsigned short input);
111     void e_shstrndx(unsigned short input);
112     void e_endian(unsigned short input);
113     // Data Interface
114     bool isValid() const;
115     int wordSize() const;
116     Elf_X_Phdr &get_phdr(unsigned int i = 0);
117     Elf_X_Shdr &get_shdr(unsigned int i);
118
119     bool findDebugFile(std::string origfilename, std::string &output_name, char* &output_buffer, unsigned long &output_buffer_size);
120
121     Dyninst::Architecture getArch() const;
122
123   protected:
124     Elf *elf;
125     Elf32_Ehdr *ehdr32;
126     Elf64_Ehdr *ehdr64;
127     Elf32_Phdr *phdr32;
128     Elf64_Phdr *phdr64;
129     int filedes;
130     bool is64;
131     bool isArchive;
132     bool isBigEndian;
133     std::vector<Elf_X_Shdr> shdrs;
134     std::vector<Elf_X_Phdr> phdrs;
135     unsigned int ref_count;
136     std::string filename;
137
138     char *cached_debug_buffer;
139     unsigned long cached_debug_size;
140     std::string cached_debug_name;
141     bool cached_debug;
142
143     Elf_X();
144     Elf_X(int input, Elf_Cmd cmd, Elf_X *ref = NULL);
145     Elf_X(char *mem_image, size_t mem_size);
146     ~Elf_X();
147
148     // Two maps:
149     // One name/FD for Elf_Xs created that way
150     // One name/baseaddr
151
152     static std::map<std::pair<std::string, int >, Elf_X *> elf_x_by_fd;
153     static std::map<std::pair<std::string, char *>, Elf_X *> elf_x_by_ptr;
154
155 };
156
157 // ------------------------------------------------------------------------
158 // Class Elf_X_Phdr simulates the Elf(32|64)_Phdr structure.
159 class DYNELF_EXPORT Elf_X_Phdr {
160    friend class Elf_X;
161   public:
162     Elf_X_Phdr();
163     Elf_X_Phdr(bool is64_, void *input);
164
165     // Read Interface
166     unsigned long p_type() const;
167     unsigned long p_offset() const;
168     unsigned long p_vaddr() const;
169     unsigned long p_paddr() const;
170     unsigned long p_filesz() const;
171     unsigned long p_memsz() const;
172     unsigned long p_flags() const;
173     unsigned long p_align() const;
174
175     // Write Interface
176     void p_type(unsigned long input);
177     void p_offset(unsigned long input);
178     void p_vaddr(unsigned long input);
179     void p_paddr(unsigned long input);
180     void p_filesz(unsigned long input);
181     void p_memsz(unsigned long input);
182     void p_flags(unsigned long input);
183     void p_align(unsigned long input);
184
185     bool isValid() const;
186
187   private:
188     Elf32_Phdr *phdr32;
189     Elf64_Phdr *phdr64;
190     bool is64;
191 };
192
193 // ------------------------------------------------------------------------
194 // Class Elf_X_Shdr simulates the Elf(32|64)_Shdr structure.
195 class DYNELF_EXPORT Elf_X_Shdr {
196     friend class Elf_X;
197
198   public:
199     Elf_X_Shdr();
200     Elf_X_Shdr(bool is64_, Elf_Scn *input);
201
202     // Read Interface
203     unsigned long sh_name() const;
204     unsigned long sh_type() const;
205     unsigned long sh_flags() const;
206     unsigned long sh_addr() const;
207     unsigned long sh_offset() const;
208     unsigned long sh_size() const;
209     unsigned long sh_link() const;
210     unsigned long sh_info() const;
211     unsigned long sh_addralign() const;
212     unsigned long sh_entsize() const;
213     bool isFromDebugFile() const;
214
215     // Write Interface
216     void sh_name(unsigned long input);
217     void sh_type(unsigned long input);
218     void sh_flags(unsigned long input);
219     void sh_addr(unsigned long input);
220     void sh_offset(unsigned long input);
221     void sh_size(unsigned long input);
222     void sh_link(unsigned long input);
223     void sh_info(unsigned long input);
224     void sh_addralign(unsigned long input);
225     void sh_entsize(unsigned long input);
226     void setDebugFile(bool b);
227
228     // Section Data Interface
229     Elf_X_Data get_data() const;
230
231     // For Sections with Multiple Data Sections
232     void first_data();
233     bool next_data();
234
235     bool isValid() const;
236     unsigned wordSize() const;
237     Elf_Scn *getScn() const;
238
239     Elf_X_Nhdr get_note() const;
240
241   protected:
242     Elf_Scn *scn;
243     Elf_Data *data;
244     Elf32_Shdr *shdr32;
245     Elf64_Shdr *shdr64;
246     bool is64;
247     bool fromDebugFile;
248     const Elf_X *_elf;
249 };
250
251 // ------------------------------------------------------------------------
252 // Class Elf_X_Data simulates the Elf_Data structure.
253 class DYNELF_EXPORT Elf_X_Data {
254   public:
255     Elf_X_Data();
256     Elf_X_Data(bool is64_, Elf_Data *input);
257
258     // Read Interface
259     void *d_buf() const;
260     Elf_Type d_type() const;
261     unsigned int d_version() const;
262     size_t d_size() const;
263     off_t d_off() const;
264     size_t d_align() const;
265     void xlatetom(unsigned int encode);
266     void xlatetof(unsigned int encode);
267
268     // Write Interface
269     void d_buf(void *input);
270     void d_type(Elf_Type input);
271     void d_version(unsigned int input);
272     void d_size(unsigned int input);
273     void d_off(signed int input);
274     void d_align(unsigned int input);
275
276     // Data Interface
277     const char *get_string() const;
278     Elf_X_Dyn get_dyn();
279     Elf_X_Versym get_versyms();
280     Elf_X_Verneed *get_verNeedSym();
281     Elf_X_Verdef *get_verDefSym();
282
283     Elf_X_Rel get_rel();
284     Elf_X_Rela get_rela();
285     Elf_X_Sym get_sym();
286
287     bool isValid() const;
288
289   protected:
290     Elf_Data *data;
291     bool is64;
292 };
293
294 // ------------------------------------------------------------------------
295 // Class Elf_X_Versym simulates the SHT_GNU_versym structure.
296 class DYNELF_EXPORT Elf_X_Versym {
297   public:
298     Elf_X_Versym();
299     Elf_X_Versym(bool is64_, Elf_Data *input);
300
301     // Read Interface
302     unsigned long get(int i) const;
303
304     // Meta-Info Interface
305     unsigned long count() const;
306     bool isValid() const;
307
308   protected:
309     Elf_Data *data;
310     Elf32_Half *versym32;
311     Elf64_Half *versym64;
312     bool is64;
313 };
314
315 // ------------------------------------------------------------------------
316 // Class Elf_X_Verdaux simulates the Elf(32|64)_Verdaux structure.
317 class DYNELF_EXPORT Elf_X_Verdaux {
318   public:
319     Elf_X_Verdaux();
320     Elf_X_Verdaux(bool is64_, void *input);
321
322     // Read Interface
323     unsigned long vda_name() const;
324     unsigned long vda_next() const;
325     Elf_X_Verdaux *get_next() const;
326
327     // Meta-Info Interface
328     bool isValid() const;
329
330   protected:
331     void *data;
332     Elf32_Verdaux *verdaux32;
333     Elf64_Verdaux *verdaux64;
334     bool is64;
335 };
336
337 // ------------------------------------------------------------------------
338 // Class Elf_X_Verdef simulates the Elf(32|64)_Verdef structure.
339 class DYNELF_EXPORT Elf_X_Verdef {
340   public:
341     Elf_X_Verdef();
342     Elf_X_Verdef(bool is64_, void *input);
343
344     // Read Interface
345     unsigned long vd_version() const;
346     unsigned long vd_flags() const;
347     unsigned long vd_ndx() const;
348     unsigned long vd_cnt() const;
349     unsigned long vd_hash() const;
350     unsigned long vd_aux() const;
351     unsigned long vd_next() const;
352     Elf_X_Verdaux *get_aux() const;
353     Elf_X_Verdef *get_next() const;
354
355     // Meta-Info Interface
356     bool isValid() const;
357    
358   protected:
359     void *data;
360     Elf32_Verdef *verdef32;
361     Elf64_Verdef *verdef64;
362     bool is64;
363 };
364
365 // ------------------------------------------------------------------------
366 // Class Elf_X_Vernaux simulates the Elf(32|64)_Vernaux structure.
367 class DYNELF_EXPORT Elf_X_Vernaux {
368   public:
369     Elf_X_Vernaux();
370     Elf_X_Vernaux(bool is64_, void *input);
371
372     // Read Interface
373     unsigned long vna_hash() const;
374     unsigned long vna_flags() const;
375     unsigned long vna_other() const;
376     unsigned long vna_name() const;
377     unsigned long vna_next() const;
378     Elf_X_Vernaux *get_next() const;
379
380     // Meta-Info Interface
381     bool isValid() const;
382
383   protected:
384     void *data;
385     Elf32_Vernaux *vernaux32;
386     Elf64_Vernaux *vernaux64;
387     bool is64;
388 };
389
390 // ------------------------------------------------------------------------
391 // Class Elf_X_Verneed simulates the Elf(32|64)_Verneed structure.
392 class DYNELF_EXPORT Elf_X_Verneed {
393   public:
394     Elf_X_Verneed();
395     Elf_X_Verneed(bool is64_, void *input);
396
397     // Read Interface
398     unsigned long vn_version() const;
399     unsigned long vn_cnt() const;
400     unsigned long vn_file() const;
401     unsigned long vn_aux() const;
402     unsigned long vn_next() const;
403     Elf_X_Vernaux *get_aux() const;
404     Elf_X_Verneed *get_next() const;
405
406     // Meta-Info Interface
407     bool isValid() const;
408
409   protected:
410     void *data;
411     Elf32_Verneed *verneed32;
412     Elf64_Verneed *verneed64;
413     bool is64;
414 };
415
416
417 // ------------------------------------------------------------------------
418 // Class Elf_X_Sym simulates the Elf(32|64)_Sym structure.
419 class DYNELF_EXPORT Elf_X_Sym {
420   public:
421     Elf_X_Sym();
422     Elf_X_Sym(bool is64_, Elf_Data *input);
423
424     // Read Interface
425     unsigned long st_name(int i) const;
426     unsigned long st_value(int i) const;
427     unsigned long st_size(int i) const;
428     unsigned char st_info(int i) const;
429     unsigned char st_other(int i) const;
430     unsigned short st_shndx(int i) const;
431     unsigned char ST_BIND(int i) const;
432     unsigned char ST_TYPE(int i) const;
433     unsigned char ST_VISIBILITY(int i) const;
434     void *st_symptr(int i) const;
435     unsigned st_entsize() const;
436
437     // Write Interface
438     void st_name(int i, unsigned long input);
439     void st_value(int i, unsigned long input);
440     void st_size(int i, unsigned long input);
441     void st_info(int i, unsigned char input);
442     void st_other(int i, unsigned char input);
443     void st_shndx(int i, unsigned short input);
444
445     // Meta-Info Interface
446     unsigned long count() const;
447     bool isValid() const;
448
449   protected:
450     Elf_Data *data;
451     Elf32_Sym *sym32;
452     Elf64_Sym *sym64;
453     bool is64;
454 };
455
456 // ------------------------------------------------------------------------
457 // Class Elf_X_Rel simulates the Elf(32|64)_Rel structure.
458 class DYNELF_EXPORT Elf_X_Rel {
459   public:
460    Elf_X_Rel();
461    Elf_X_Rel(bool is64_, Elf_Data *input);
462
463     // Read Interface
464     unsigned long r_offset(int i) const;
465     unsigned long r_info(int i) const;
466     unsigned long R_SYM(int i) const;
467     unsigned long R_TYPE(int i) const;
468
469     // Write Interface
470     void r_offset(int i, unsigned long input);
471     void r_info(int i, unsigned long input);
472
473     // Meta-Info Interface
474     unsigned long count() const;
475     bool isValid() const;
476
477   protected:
478     Elf_Data *data;
479     Elf32_Rel *rel32;
480     Elf64_Rel *rel64;
481     bool is64;
482 };
483
484 // ------------------------------------------------------------------------
485 // Class Elf_X_Rela simulates the Elf(32|64)_Rela structure.
486 class DYNELF_EXPORT Elf_X_Rela {
487   public:
488     Elf_X_Rela();
489     Elf_X_Rela(bool is64_, Elf_Data *input);
490
491     // Read Interface
492     unsigned long r_offset(int i) const;
493     unsigned long r_info(int i) const;
494     signed   long r_addend(int i) const;
495     unsigned long R_SYM(int i) const;
496     unsigned long R_TYPE(int i) const;
497
498     // Write Interface
499     void r_offset(int i, unsigned long input);
500     void r_info(int i, unsigned long input);
501     void r_addend(int i, signed long input);
502
503     // Meta-Info Interface
504     unsigned long count() const;
505     bool isValid() const;
506
507   protected:
508     Elf_Data *data;
509     Elf32_Rela *rela32;
510     Elf64_Rela *rela64;
511     bool is64;
512 };
513
514 // ------------------------------------------------------------------------
515 // Class Elf_X_Dyn simulates the Elf(32|64)_Dyn structure.
516 class DYNELF_EXPORT Elf_X_Dyn {
517   public:
518     Elf_X_Dyn();
519     Elf_X_Dyn(bool is64_, Elf_Data *input);
520
521     // Read Interface
522     signed long d_tag(int i) const;
523     unsigned long d_val(int i) const;
524     unsigned long d_ptr(int i) const;
525
526     // Write Interface
527     void d_tag(int i, signed long input);
528     void d_val(int i, unsigned long input);
529     void d_ptr(int i, unsigned long input);
530
531     // Meta-Info Interface
532     unsigned long count() const;
533     bool isValid() const;
534
535   protected:
536     Elf_Data *data;
537     Elf32_Dyn *dyn32;
538     Elf64_Dyn *dyn64;
539     bool is64;
540 };
541
542 // ------------------------------------------------------------------------
543 // Class Elf_X_Nhdr simulates the Elf(32|64)_Shdr structure.
544 class DYNELF_EXPORT Elf_X_Nhdr {
545     friend class Elf_X;
546
547   public:
548     Elf_X_Nhdr();
549     Elf_X_Nhdr(Elf_Data *data_, size_t offset);
550
551     // Read Interface
552     unsigned long n_namesz() const;
553     unsigned long n_descsz() const;
554     unsigned long n_type() const;
555
556     // Meta-Info Interface
557     bool isValid() const;
558
559     const char* get_name() const;
560     const void* get_desc() const;
561
562     Elf_X_Nhdr next() const;
563
564   protected:
565     Elf_Data *data;
566     Elf32_Nhdr *nhdr;
567 };
568
569 }
570
571 #endif