Merge branch 'vendor/OPENSSL'
[dragonfly.git] / contrib / binutils-2.20 / elfcpp / elfcpp_file.h
1 // elfcpp_file.h -- file access for elfcpp   -*- C++ -*-
2
3 // Copyright 2006, 2007, Free Software Foundation, Inc.
4 // Written by Ian Lance Taylor <iant@google.com>.
5
6 // This file is part of elfcpp.
7    
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public License
10 // as published by the Free Software Foundation; either version 2, or
11 // (at your option) any later version.
12
13 // In addition to the permissions in the GNU Library General Public
14 // License, the Free Software Foundation gives you unlimited
15 // permission to link the compiled version of this file into
16 // combinations with other programs, and to distribute those
17 // combinations without any restriction coming from the use of this
18 // file.  (The Library Public License restrictions do apply in other
19 // respects; for example, they cover modification of the file, and
20 /// distribution when not linked into a combined executable.)
21
22 // This program is distributed in the hope that it will be useful, but
23 // WITHOUT ANY WARRANTY; without even the implied warranty of
24 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25 // Library General Public License for more details.
26
27 // You should have received a copy of the GNU Library General Public
28 // License along with this program; if not, write to the Free Software
29 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
30 // 02110-1301, USA.
31
32 // This header file defines the class Elf_file which can be used to
33 // read useful data from an ELF file.  The functions here are all
34 // templates which take a file interface object as a parameter.  This
35 // type must have a subtype View.  This type must support two methods:
36 //     View view(off_t file_offset, off_t data_size)
37 // returns a View for the specified part of the file.
38 //     void error(const char* printf_format, ...)
39 // prints an error message and does not return.  The subtype View must
40 // support a method
41 //     const unsigned char* data()
42 // which returns a pointer to a buffer containing the requested data.
43 // This general interface is used to read data from the file.  Objects
44 // of type View will never survive longer than the elfcpp function.
45
46 // Some of these functions must return a reference to part of the
47 // file.  To use these, the file interface must support a subtype
48 // Location:
49 //    Location(off_t file_offset, off_t data_size)
50 // To use this in conjunction with the accessors types Shdr, etc., the
51 // file interface should support an overload of view:
52 //    View view(Location)
53 // This permits writing
54 //    elfcpp::Shdr shdr(file, ef.section_header(n));
55
56 #ifndef ELFCPP_FILE_H
57 #define ELFCPP_FILE_H
58
59 #include <string>
60 #include <cstdio>
61 #include <cstring>
62
63 namespace elfcpp
64 {
65
66 // A simple helper class to recognize if a file has an ELF header.
67
68 class Elf_recognizer
69 {
70  public:
71   // Maximum header size.  The user should try to read this much of
72   // the file when using this class.
73
74   static const int max_header_size = Elf_sizes<64>::ehdr_size;
75
76   // Checks if the file contains the ELF magic.  Other header fields
77   // are not checked.
78
79   static bool
80   is_elf_file(const unsigned char* ehdr_buf, int size);
81
82   // Check if EHDR_BUF/BUFSIZE is a valid header of a 32-bit or
83   // 64-bit, little-endian or big-endian ELF file.  Assumes
84   // is_elf_file() has been checked to be true.  If the header is not
85   // valid, *ERROR contains a human-readable error message.  If is is,
86   // *SIZE is set to either 32 or 64, *BIG_ENDIAN is set to indicate
87   // whether the file is big-endian.
88
89   static bool
90   is_valid_header(const unsigned char* ehdr_buf, off_t bufsize,
91                   int* size, bool* big_endian,
92                   std::string* error);
93 };
94
95 // This object is used to read an ELF file.
96 //   SIZE: The size of file, 32 or 64.
97 //   BIG_ENDIAN: Whether the file is in big-endian format.
98 //   FILE: A file reading type as described above.
99
100 template<int size, bool big_endian, typename File>
101 class Elf_file
102 {
103  private:
104   typedef Elf_file<size, big_endian, File> This;
105
106  public:
107   static const int ehdr_size = Elf_sizes<size>::ehdr_size;
108   static const int phdr_size = Elf_sizes<size>::phdr_size;
109   static const int shdr_size = Elf_sizes<size>::shdr_size;
110   static const int sym_size = Elf_sizes<size>::sym_size;
111   static const int rel_size = Elf_sizes<size>::rel_size;
112   static const int rela_size = Elf_sizes<size>::rela_size;
113
114   typedef Ehdr<size, big_endian> Ef_ehdr;
115   typedef Phdr<size, big_endian> Ef_phdr;
116   typedef Shdr<size, big_endian> Ef_shdr;
117   typedef Sym<size, big_endian> Ef_sym;
118
119   // Construct an Elf_file given an ELF file header.
120   Elf_file(File* file, const Ef_ehdr& ehdr)
121   { this->construct(file, ehdr); }
122
123   // Construct an ELF file.
124   inline
125   Elf_file(File* file);
126
127   // Return the file offset to the section headers.
128   off_t
129   shoff() const
130   { return this->shoff_; }
131
132   // Find the first section with an sh_type field equal to TYPE and
133   // return its index.  Returns SHN_UNDEF if there is no such section.
134   unsigned int
135   find_section_by_type(unsigned int type);
136
137   // Return the number of sections.
138   unsigned int
139   shnum()
140   {
141     this->initialize_shnum();
142     return this->shnum_;
143   }
144
145   // Return the section index of the section name string table.
146   unsigned int
147   shstrndx()
148   {
149     this->initialize_shnum();
150     return this->shstrndx_;
151   }
152
153   // Return the value to subtract from section indexes >=
154   // SHN_LORESERVE.  See the comment in initialize_shnum.
155   int
156   large_shndx_offset()
157   {
158     this->initialize_shnum();
159     return this->large_shndx_offset_;
160   }
161
162   // Return the location of the header of section SHNDX.
163   typename File::Location
164   section_header(unsigned int shndx)
165   {
166     return typename File::Location(this->section_header_offset(shndx),
167                                    shdr_size);
168   }
169
170   // Return the name of section SHNDX.
171   std::string
172   section_name(unsigned int shndx);
173
174   // Return the location of the contents of section SHNDX.
175   typename File::Location
176   section_contents(unsigned int shndx);
177
178   // Return the size of section SHNDX.
179   typename Elf_types<size>::Elf_WXword
180   section_size(unsigned int shndx);
181
182   // Return the flags of section SHNDX.
183   typename Elf_types<size>::Elf_WXword
184   section_flags(unsigned int shndx);
185
186   // Return the address of section SHNDX.
187   typename Elf_types<size>::Elf_Addr
188   section_addr(unsigned int shndx);
189
190   // Return the type of section SHNDX.
191   Elf_Word
192   section_type(unsigned int shndx);
193
194   // Return the link field of section SHNDX.
195   Elf_Word
196   section_link(unsigned int shndx);
197
198   // Return the info field of section SHNDX.
199   Elf_Word
200   section_info(unsigned int shndx);
201
202   // Return the addralign field of section SHNDX.
203   typename Elf_types<size>::Elf_WXword
204   section_addralign(unsigned int shndx);
205
206  private:
207   // Shared constructor code.
208   void
209   construct(File* file, const Ef_ehdr& ehdr);
210
211   // Initialize shnum_ and shstrndx_.
212   void
213   initialize_shnum();
214
215   // Return the file offset of the header of section SHNDX.
216   off_t
217   section_header_offset(unsigned int shndx);
218
219   // The file we are reading.
220   File* file_;
221   // The file offset to the section headers.
222   off_t shoff_;
223   // The number of sections.
224   unsigned int shnum_;
225   // The section index of the section name string table.
226   unsigned int shstrndx_;
227   // Offset to add to sections larger than SHN_LORESERVE.
228   int large_shndx_offset_;
229 };
230
231 // A small wrapper around SHT_STRTAB data mapped to memory. It checks that the
232 // index is not out of bounds and the string is NULL-terminated.
233
234 class Elf_strtab
235 {
236  public:
237   // Construct an Elf_strtab for a section with contents *P and size SIZE.
238   Elf_strtab(const unsigned char* p, size_t size);
239
240   // Return the file offset to the section headers.
241   bool
242   get_c_string(size_t offset, const char** cstring) const
243   {
244     if (offset >= this->usable_size_)
245       return false;
246     *cstring = this->base_ + offset;
247     return true;
248   }
249
250  private:
251   // Contents of the section mapped to memory.
252   const char* base_;
253   // One larger that the position of the last NULL character in the section.
254   // For valid SHT_STRTAB sections, this is the size of the section.
255   size_t usable_size_;
256 };
257
258 // Inline function definitions.
259
260 // Check for presence of the ELF magic number.
261
262 inline bool
263 Elf_recognizer::is_elf_file(const unsigned char* ehdr_buf, int size)
264 {
265   if (size < 4)
266     return false;
267
268   static unsigned char elfmagic[4] =
269     {
270       elfcpp::ELFMAG0, elfcpp::ELFMAG1,
271       elfcpp::ELFMAG2, elfcpp::ELFMAG3
272     };
273   return memcmp(ehdr_buf, elfmagic, 4) == 0;
274 }
275
276 namespace
277 {
278
279 // Print a number to a string.
280
281 inline std::string
282 internal_printf_int(const char* format, int arg)
283 {
284   char buf[256];
285   snprintf(buf, sizeof(buf), format, arg);
286   return std::string(buf);
287 }
288
289 }  // End anonymous namespace.
290
291 // Check the validity of the ELF header.
292
293 inline bool
294 Elf_recognizer::is_valid_header(
295     const unsigned char* ehdr_buf,
296     off_t bufsize,
297     int* size,
298     bool* big_endian,
299     std::string* error)
300 {
301   if (bufsize < elfcpp::EI_NIDENT)
302     {
303       *error = _("ELF file too short");
304       return false;
305     }
306
307   int v = ehdr_buf[elfcpp::EI_VERSION];
308   if (v != elfcpp::EV_CURRENT)
309     {
310       if (v == elfcpp::EV_NONE)
311         *error = _("invalid ELF version 0");
312       else
313         *error = internal_printf_int(_("unsupported ELF version %d"), v);
314       return false;
315     }
316
317   int c = ehdr_buf[elfcpp::EI_CLASS];
318   if (c == elfcpp::ELFCLASSNONE)
319     {
320       *error = _("invalid ELF class 0");
321       return false;
322     }
323   else if (c != elfcpp::ELFCLASS32
324            && c != elfcpp::ELFCLASS64)
325     {
326       *error = internal_printf_int(_("unsupported ELF class %d"), c);
327       return false;
328     }
329
330   int d = ehdr_buf[elfcpp::EI_DATA];
331   if (d == elfcpp::ELFDATANONE)
332     {
333       *error = _("invalid ELF data encoding");
334       return false;
335     }
336   else if (d != elfcpp::ELFDATA2LSB
337            && d != elfcpp::ELFDATA2MSB)
338     {
339       *error = internal_printf_int(_("unsupported ELF data encoding %d"), d);
340       return false;
341     }
342
343   *big_endian = (d == elfcpp::ELFDATA2MSB);
344
345   if (c == elfcpp::ELFCLASS32)
346     {
347       if (bufsize < elfcpp::Elf_sizes<32>::ehdr_size)
348         {
349           *error = _("ELF file too short");
350           return false;
351         }
352       *size = 32;
353     }
354   else
355     {
356       if (bufsize < elfcpp::Elf_sizes<64>::ehdr_size)
357         {
358           *error = _("ELF file too short");
359           return false;
360         }
361       *size = 64;
362     }
363
364   return true;
365 }
366
367 // Template function definitions.
368
369 // Construct an Elf_file given an ELF file header.
370
371 template<int size, bool big_endian, typename File>
372 void
373 Elf_file<size, big_endian, File>::construct(File* file, const Ef_ehdr& ehdr)
374 {
375   this->file_ = file;
376   this->shoff_ = ehdr.get_e_shoff();
377   this->shnum_ = ehdr.get_e_shnum();
378   this->shstrndx_ = ehdr.get_e_shstrndx();
379   this->large_shndx_offset_ = 0;
380   if (ehdr.get_e_ehsize() != This::ehdr_size)
381     file->error(_("bad e_ehsize (%d != %d)"),
382                 ehdr.get_e_ehsize(), This::ehdr_size);
383   if (ehdr.get_e_shentsize() != This::shdr_size)
384     file->error(_("bad e_shentsize (%d != %d)"),
385                 ehdr.get_e_shentsize(), This::shdr_size);
386 }
387
388 // Construct an ELF file.
389
390 template<int size, bool big_endian, typename File>
391 inline
392 Elf_file<size, big_endian, File>::Elf_file(File* file)
393 {
394   typename File::View v(file->view(file_header_offset, This::ehdr_size));
395   this->construct(file, Ef_ehdr(v.data()));
396 }
397
398 // Initialize the shnum_ and shstrndx_ fields, handling overflow.
399
400 template<int size, bool big_endian, typename File>
401 void
402 Elf_file<size, big_endian, File>::initialize_shnum()
403 {
404   if ((this->shnum_ == 0 || this->shstrndx_ == SHN_XINDEX)
405       && this->shoff_ != 0)
406     {
407       typename File::View v(this->file_->view(this->shoff_, This::shdr_size));
408       Ef_shdr shdr(v.data());
409
410       if (this->shnum_ == 0)
411         this->shnum_ = shdr.get_sh_size();
412
413       if (this->shstrndx_ == SHN_XINDEX)
414         {
415           this->shstrndx_ = shdr.get_sh_link();
416
417           // Versions of the GNU binutils between 2.12 and 2.18 did
418           // not handle objects with more than SHN_LORESERVE sections
419           // correctly.  All large section indexes were offset by
420           // 0x100.  Some information can be found here:
421           // http://sourceware.org/bugzilla/show_bug.cgi?id=5900 .
422           // Fortunately these object files are easy to detect, as the
423           // GNU binutils always put the section header string table
424           // near the end of the list of sections.  Thus if the
425           // section header string table index is larger than the
426           // number of sections, then we know we have to subtract
427           // 0x100 to get the real section index.
428           if (this->shstrndx_ >= this->shnum_)
429             {
430               if (this->shstrndx_ >= elfcpp::SHN_LORESERVE + 0x100)
431                 {
432                   this->large_shndx_offset_ = - 0x100;
433                   this->shstrndx_ -= 0x100;
434                 }
435               if (this->shstrndx_ >= this->shnum_)
436                 this->file_->error(_("bad shstrndx: %u >= %u"),
437                                    this->shstrndx_, this->shnum_);
438             }
439         }
440     }
441 }
442
443 // Find section with sh_type equal to TYPE and return its index.
444 // Returns SHN_UNDEF if not found.
445
446 template<int size, bool big_endian, typename File>
447 unsigned int
448 Elf_file<size, big_endian, File>::find_section_by_type(unsigned int type)
449 {
450   unsigned int shnum = this->shnum();
451   typename File::View v(this->file_->view(this->shoff_,
452                                           This::shdr_size * shnum));
453   for (unsigned int i = 0; i < shnum; i++)
454     {
455       Ef_shdr shdr(v.data() + This::shdr_size * i);
456       if (shdr.get_sh_type() == type)
457         return i;
458     }
459   return SHN_UNDEF;
460 }
461
462 // Return the file offset of the section header of section SHNDX.
463
464 template<int size, bool big_endian, typename File>
465 off_t
466 Elf_file<size, big_endian, File>::section_header_offset(unsigned int shndx)
467 {
468   if (shndx >= this->shnum())
469     this->file_->error(_("section_header_offset: bad shndx %u >= %u"),
470                        shndx, this->shnum());
471   return this->shoff_ + This::shdr_size * shndx;
472 }
473
474 // Return the name of section SHNDX.
475
476 template<int size, bool big_endian, typename File>
477 std::string
478 Elf_file<size, big_endian, File>::section_name(unsigned int shndx)
479 {
480   File* const file = this->file_;
481
482   // Get the section name offset.
483   unsigned int sh_name;
484   {
485     typename File::View v(file->view(this->section_header_offset(shndx),
486                                      This::shdr_size));
487     Ef_shdr shdr(v.data());
488     sh_name = shdr.get_sh_name();
489   }
490
491   // Get the file offset for the section name string table data.
492   off_t shstr_off;
493   typename Elf_types<size>::Elf_WXword shstr_size;
494   {
495     const unsigned int shstrndx = this->shstrndx_;
496     typename File::View v(file->view(this->section_header_offset(shstrndx),
497                                      This::shdr_size));
498     Ef_shdr shstr_shdr(v.data());
499     shstr_off = shstr_shdr.get_sh_offset();
500     shstr_size = shstr_shdr.get_sh_size();
501   }
502
503   if (sh_name >= shstr_size)
504     file->error(_("bad section name offset for section %u: %u"),
505                 shndx, sh_name);
506
507   typename File::View v(file->view(shstr_off, shstr_size));
508
509   const unsigned char* datau = v.data();
510   const char* data = reinterpret_cast<const char*>(datau);
511   const void* p = ::memchr(data + sh_name, '\0', shstr_size - sh_name);
512   if (p == NULL)
513     file->error(_("missing null terminator for name of section %u"),
514                 shndx);
515
516   size_t len = static_cast<const char*>(p) - (data + sh_name);
517
518   return std::string(data + sh_name, len);
519 }
520
521 // Return the contents of section SHNDX.
522
523 template<int size, bool big_endian, typename File>
524 typename File::Location
525 Elf_file<size, big_endian, File>::section_contents(unsigned int shndx)
526 {
527   File* const file = this->file_;
528
529   if (shndx >= this->shnum())
530     file->error(_("section_contents: bad shndx %u >= %u"),
531                 shndx, this->shnum());
532
533   typename File::View v(file->view(this->section_header_offset(shndx),
534                                    This::shdr_size));
535   Ef_shdr shdr(v.data());
536   return typename File::Location(shdr.get_sh_offset(), shdr.get_sh_size());
537 }
538
539 // Get the size of section SHNDX.
540
541 template<int size, bool big_endian, typename File>
542 typename Elf_types<size>::Elf_WXword
543 Elf_file<size, big_endian, File>::section_size(unsigned int shndx)
544 {
545   File* const file = this->file_;
546
547   if (shndx >= this->shnum())
548     file->error(_("section_size: bad shndx %u >= %u"),
549                 shndx, this->shnum());
550
551   typename File::View v(file->view(this->section_header_offset(shndx),
552                                    This::shdr_size));
553
554   Ef_shdr shdr(v.data());
555   return shdr.get_sh_size();
556 }
557
558 // Return the section flags of section SHNDX.
559
560 template<int size, bool big_endian, typename File>
561 typename Elf_types<size>::Elf_WXword
562 Elf_file<size, big_endian, File>::section_flags(unsigned int shndx)
563 {
564   File* const file = this->file_;
565
566   if (shndx >= this->shnum())
567     file->error(_("section_flags: bad shndx %u >= %u"),
568                 shndx, this->shnum());
569
570   typename File::View v(file->view(this->section_header_offset(shndx),
571                                    This::shdr_size));
572
573   Ef_shdr shdr(v.data());
574   return shdr.get_sh_flags();
575 }
576
577 // Return the address of section SHNDX.
578
579 template<int size, bool big_endian, typename File>
580 typename Elf_types<size>::Elf_Addr
581 Elf_file<size, big_endian, File>::section_addr(unsigned int shndx)
582 {
583   File* const file = this->file_;
584
585   if (shndx >= this->shnum())
586     file->error(_("section_flags: bad shndx %u >= %u"),
587                 shndx, this->shnum());
588
589   typename File::View v(file->view(this->section_header_offset(shndx),
590                                    This::shdr_size));
591
592   Ef_shdr shdr(v.data());
593   return shdr.get_sh_addr();
594 }
595
596 // Return the type of section SHNDX.
597
598 template<int size, bool big_endian, typename File>
599 Elf_Word
600 Elf_file<size, big_endian, File>::section_type(unsigned int shndx)
601 {
602   File* const file = this->file_;
603
604   if (shndx >= this->shnum())
605     file->error(_("section_type: bad shndx %u >= %u"),
606                 shndx, this->shnum());
607
608   typename File::View v(file->view(this->section_header_offset(shndx),
609                                    This::shdr_size));
610
611   Ef_shdr shdr(v.data());
612   return shdr.get_sh_type();
613 }
614
615 // Return the sh_link field of section SHNDX.
616
617 template<int size, bool big_endian, typename File>
618 Elf_Word
619 Elf_file<size, big_endian, File>::section_link(unsigned int shndx)
620 {
621   File* const file = this->file_;
622
623   if (shndx >= this->shnum())
624     file->error(_("section_link: bad shndx %u >= %u"),
625                 shndx, this->shnum());
626
627   typename File::View v(file->view(this->section_header_offset(shndx),
628                                    This::shdr_size));
629
630   Ef_shdr shdr(v.data());
631   return shdr.get_sh_link();
632 }
633
634 // Return the sh_info field of section SHNDX.
635
636 template<int size, bool big_endian, typename File>
637 Elf_Word
638 Elf_file<size, big_endian, File>::section_info(unsigned int shndx)
639 {
640   File* const file = this->file_;
641
642   if (shndx >= this->shnum())
643     file->error(_("section_info: bad shndx %u >= %u"),
644                 shndx, this->shnum());
645
646   typename File::View v(file->view(this->section_header_offset(shndx),
647                                    This::shdr_size));
648
649   Ef_shdr shdr(v.data());
650   return shdr.get_sh_info();
651 }
652
653 // Return the sh_addralign field of section SHNDX.
654
655 template<int size, bool big_endian, typename File>
656 typename Elf_types<size>::Elf_WXword
657 Elf_file<size, big_endian, File>::section_addralign(unsigned int shndx)
658 {
659   File* const file = this->file_;
660
661   if (shndx >= this->shnum())
662     file->error(_("section_addralign: bad shndx %u >= %u"),
663                 shndx, this->shnum());
664
665   typename File::View v(file->view(this->section_header_offset(shndx),
666                                    This::shdr_size));
667
668   Ef_shdr shdr(v.data());
669   return shdr.get_sh_addralign();
670 }
671
672 inline
673 Elf_strtab::Elf_strtab(const unsigned char* p, size_t size)
674 {
675   // Check if the section is NUL-terminated. If it isn't, we ignore
676   // the last part to make sure we don't return non-NUL-terminated
677   // strings.
678   while (size > 0 && p[size - 1] != 0)
679     size--;
680   this->base_ = reinterpret_cast<const char*>(p);
681   this->usable_size_ = size;
682 }
683
684 } // End namespace elfcpp.
685
686 #endif // !defined(ELFCPP_FILE_H)