elfcpp/:
[external/binutils.git] / 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 // Inline function definitions.
232
233 // Check for presence of the ELF magic number.
234
235 inline bool
236 Elf_recognizer::is_elf_file(const unsigned char* ehdr_buf, int size)
237 {
238   if (size < 4)
239     return false;
240
241   static unsigned char elfmagic[4] =
242     {
243       elfcpp::ELFMAG0, elfcpp::ELFMAG1,
244       elfcpp::ELFMAG2, elfcpp::ELFMAG3
245     };
246   return memcmp(ehdr_buf, elfmagic, 4) == 0;
247 }
248
249 namespace
250 {
251
252 // Print a number to a string.
253
254 inline std::string
255 internal_printf_int(const char* format, int arg)
256 {
257   char buf[256];
258   snprintf(buf, sizeof(buf), format, arg);
259   return std::string(buf);
260 }
261
262 }  // End anonymous namespace.
263
264 // Check the validity of the ELF header.
265
266 inline bool
267 Elf_recognizer::is_valid_header(
268     const unsigned char* ehdr_buf,
269     off_t bufsize,
270     int* size,
271     bool* big_endian,
272     std::string* error)
273 {
274   if (bufsize < elfcpp::EI_NIDENT)
275     {
276       *error = _("ELF file too short");
277       return false;
278     }
279
280   int v = ehdr_buf[elfcpp::EI_VERSION];
281   if (v != elfcpp::EV_CURRENT)
282     {
283       if (v == elfcpp::EV_NONE)
284         *error = _("invalid ELF version 0");
285       else
286         *error = internal_printf_int(_("unsupported ELF version %d"), v);
287       return false;
288     }
289
290   int c = ehdr_buf[elfcpp::EI_CLASS];
291   if (c == elfcpp::ELFCLASSNONE)
292     {
293       *error = _("invalid ELF class 0");
294       return false;
295     }
296   else if (c != elfcpp::ELFCLASS32
297            && c != elfcpp::ELFCLASS64)
298     {
299       *error = internal_printf_int(_("unsupported ELF class %d"), c);
300       return false;
301     }
302
303   int d = ehdr_buf[elfcpp::EI_DATA];
304   if (d == elfcpp::ELFDATANONE)
305     {
306       *error = _("invalid ELF data encoding");
307       return false;
308     }
309   else if (d != elfcpp::ELFDATA2LSB
310            && d != elfcpp::ELFDATA2MSB)
311     {
312       *error = internal_printf_int(_("unsupported ELF data encoding %d"), d);
313       return false;
314     }
315
316   *big_endian = (d == elfcpp::ELFDATA2MSB);
317
318   if (c == elfcpp::ELFCLASS32)
319     {
320       if (bufsize < elfcpp::Elf_sizes<32>::ehdr_size)
321         {
322           *error = _("ELF file too short");
323           return false;
324         }
325       *size = 32;
326     }
327   else
328     {
329       if (bufsize < elfcpp::Elf_sizes<64>::ehdr_size)
330         {
331           *error = _("ELF file too short");
332           return false;
333         }
334       *size = 64;
335     }
336
337   return true;
338 }
339
340 // Template function definitions.
341
342 // Construct an Elf_file given an ELF file header.
343
344 template<int size, bool big_endian, typename File>
345 void
346 Elf_file<size, big_endian, File>::construct(File* file, const Ef_ehdr& ehdr)
347 {
348   this->file_ = file;
349   this->shoff_ = ehdr.get_e_shoff();
350   this->shnum_ = ehdr.get_e_shnum();
351   this->shstrndx_ = ehdr.get_e_shstrndx();
352   this->large_shndx_offset_ = 0;
353   if (ehdr.get_e_ehsize() != This::ehdr_size)
354     file->error(_("bad e_ehsize (%d != %d)"),
355                 ehdr.get_e_ehsize(), This::ehdr_size);
356   if (ehdr.get_e_shentsize() != This::shdr_size)
357     file->error(_("bad e_shentsize (%d != %d)"),
358                 ehdr.get_e_shentsize(), This::shdr_size);
359 }
360
361 // Construct an ELF file.
362
363 template<int size, bool big_endian, typename File>
364 inline
365 Elf_file<size, big_endian, File>::Elf_file(File* file)
366 {
367   typename File::View v(file->view(file_header_offset, This::ehdr_size));
368   this->construct(file, Ef_ehdr(v.data()));
369 }
370
371 // Initialize the shnum_ and shstrndx_ fields, handling overflow.
372
373 template<int size, bool big_endian, typename File>
374 void
375 Elf_file<size, big_endian, File>::initialize_shnum()
376 {
377   if ((this->shnum_ == 0 || this->shstrndx_ == SHN_XINDEX)
378       && this->shoff_ != 0)
379     {
380       typename File::View v(this->file_->view(this->shoff_, This::shdr_size));
381       Ef_shdr shdr(v.data());
382
383       if (this->shnum_ == 0)
384         this->shnum_ = shdr.get_sh_size();
385
386       if (this->shstrndx_ == SHN_XINDEX)
387         {
388           this->shstrndx_ = shdr.get_sh_link();
389
390           // Versions of the GNU binutils between 2.12 and 2.18 did
391           // not handle objects with more than SHN_LORESERVE sections
392           // correctly.  All large section indexes were offset by
393           // 0x100.  Some information can be found here:
394           // http://sourceware.org/bugzilla/show_bug.cgi?id=5900 .
395           // Fortunately these object files are easy to detect, as the
396           // GNU binutils always put the section header string table
397           // near the end of the list of sections.  Thus if the
398           // section header string table index is larger than the
399           // number of sections, then we know we have to subtract
400           // 0x100 to get the real section index.
401           if (this->shstrndx_ >= this->shnum_)
402             {
403               if (this->shstrndx_ >= elfcpp::SHN_LORESERVE + 0x100)
404                 {
405                   this->large_shndx_offset_ = - 0x100;
406                   this->shstrndx_ -= 0x100;
407                 }
408               if (this->shstrndx_ >= this->shnum_)
409                 this->file_->error(_("bad shstrndx: %u >= %u"),
410                                    this->shstrndx_, this->shnum_);
411             }
412         }
413     }
414 }
415
416 // Find section with sh_type equal to TYPE and return its index.
417 // Returns SHN_UNDEF if not found.
418
419 template<int size, bool big_endian, typename File>
420 unsigned int
421 Elf_file<size, big_endian, File>::find_section_by_type(unsigned int type)
422 {
423   unsigned int shnum = this->shnum();
424   typename File::View v(this->file_->view(this->shoff_,
425                                           This::shdr_size * shnum));
426   for (unsigned int i = 0; i < shnum; i++)
427     {
428       Ef_shdr shdr(v.data() + This::shdr_size * i);
429       if (shdr.get_sh_type() == type)
430         return i;
431     }
432   return SHN_UNDEF;
433 }
434
435 // Return the file offset of the section header of section SHNDX.
436
437 template<int size, bool big_endian, typename File>
438 off_t
439 Elf_file<size, big_endian, File>::section_header_offset(unsigned int shndx)
440 {
441   if (shndx >= this->shnum())
442     this->file_->error(_("section_header_offset: bad shndx %u >= %u"),
443                        shndx, this->shnum());
444   return this->shoff_ + This::shdr_size * shndx;
445 }
446
447 // Return the name of section SHNDX.
448
449 template<int size, bool big_endian, typename File>
450 std::string
451 Elf_file<size, big_endian, File>::section_name(unsigned int shndx)
452 {
453   File* const file = this->file_;
454
455   // Get the section name offset.
456   unsigned int sh_name;
457   {
458     typename File::View v(file->view(this->section_header_offset(shndx),
459                                      This::shdr_size));
460     Ef_shdr shdr(v.data());
461     sh_name = shdr.get_sh_name();
462   }
463
464   // Get the file offset for the section name string table data.
465   off_t shstr_off;
466   off_t shstr_size;
467   {
468     const unsigned int shstrndx = this->shstrndx_;
469     typename File::View v(file->view(this->section_header_offset(shstrndx),
470                                      This::shdr_size));
471     Ef_shdr shstr_shdr(v.data());
472     shstr_off = shstr_shdr.get_sh_offset();
473     shstr_size = shstr_shdr.get_sh_size();
474   }
475
476   if (sh_name >= shstr_size)
477     file->error(_("bad section name offset for section %u: %u"),
478                 shndx, sh_name);
479
480   typename File::View v(file->view(shstr_off, shstr_size));
481
482   const unsigned char* datau = v.data();
483   const char* data = reinterpret_cast<const char*>(datau);
484   const void* p = ::memchr(data + sh_name, '\0', shstr_size - sh_name);
485   if (p == NULL)
486     file->error(_("missing null terminator for name of section %u"),
487                 shndx);
488
489   size_t len = static_cast<const char*>(p) - (data + sh_name);
490
491   return std::string(data + sh_name, len);
492 }
493
494 // Return the contents of section SHNDX.
495
496 template<int size, bool big_endian, typename File>
497 typename File::Location
498 Elf_file<size, big_endian, File>::section_contents(unsigned int shndx)
499 {
500   File* const file = this->file_;
501
502   if (shndx >= this->shnum())
503     file->error(_("section_contents: bad shndx %u >= %u"),
504                 shndx, this->shnum());
505
506   typename File::View v(file->view(this->section_header_offset(shndx),
507                                    This::shdr_size));
508   Ef_shdr shdr(v.data());
509   return typename File::Location(shdr.get_sh_offset(), shdr.get_sh_size());
510 }
511
512 // Get the size of section SHNDX.
513
514 template<int size, bool big_endian, typename File>
515 typename Elf_types<size>::Elf_WXword
516 Elf_file<size, big_endian, File>::section_size(unsigned int shndx)
517 {
518   File* const file = this->file_;
519
520   if (shndx >= this->shnum())
521     file->error(_("section_size: bad shndx %u >= %u"),
522                 shndx, this->shnum());
523
524   typename File::View v(file->view(this->section_header_offset(shndx),
525                                    This::shdr_size));
526
527   Ef_shdr shdr(v.data());
528   return shdr.get_sh_size();
529 }
530
531 // Return the section flags of section SHNDX.
532
533 template<int size, bool big_endian, typename File>
534 typename Elf_types<size>::Elf_WXword
535 Elf_file<size, big_endian, File>::section_flags(unsigned int shndx)
536 {
537   File* const file = this->file_;
538
539   if (shndx >= this->shnum())
540     file->error(_("section_flags: bad shndx %u >= %u"),
541                 shndx, this->shnum());
542
543   typename File::View v(file->view(this->section_header_offset(shndx),
544                                    This::shdr_size));
545
546   Ef_shdr shdr(v.data());
547   return shdr.get_sh_flags();
548 }
549
550 // Return the address of section SHNDX.
551
552 template<int size, bool big_endian, typename File>
553 typename Elf_types<size>::Elf_Addr
554 Elf_file<size, big_endian, File>::section_addr(unsigned int shndx)
555 {
556   File* const file = this->file_;
557
558   if (shndx >= this->shnum())
559     file->error(_("section_flags: bad shndx %u >= %u"),
560                 shndx, this->shnum());
561
562   typename File::View v(file->view(this->section_header_offset(shndx),
563                                    This::shdr_size));
564
565   Ef_shdr shdr(v.data());
566   return shdr.get_sh_addr();
567 }
568
569 // Return the type of section SHNDX.
570
571 template<int size, bool big_endian, typename File>
572 Elf_Word
573 Elf_file<size, big_endian, File>::section_type(unsigned int shndx)
574 {
575   File* const file = this->file_;
576
577   if (shndx >= this->shnum())
578     file->error(_("section_type: bad shndx %u >= %u"),
579                 shndx, this->shnum());
580
581   typename File::View v(file->view(this->section_header_offset(shndx),
582                                    This::shdr_size));
583
584   Ef_shdr shdr(v.data());
585   return shdr.get_sh_type();
586 }
587
588 // Return the sh_link field of section SHNDX.
589
590 template<int size, bool big_endian, typename File>
591 Elf_Word
592 Elf_file<size, big_endian, File>::section_link(unsigned int shndx)
593 {
594   File* const file = this->file_;
595
596   if (shndx >= this->shnum())
597     file->error(_("section_link: bad shndx %u >= %u"),
598                 shndx, this->shnum());
599
600   typename File::View v(file->view(this->section_header_offset(shndx),
601                                    This::shdr_size));
602
603   Ef_shdr shdr(v.data());
604   return shdr.get_sh_link();
605 }
606
607 // Return the sh_info field of section SHNDX.
608
609 template<int size, bool big_endian, typename File>
610 Elf_Word
611 Elf_file<size, big_endian, File>::section_info(unsigned int shndx)
612 {
613   File* const file = this->file_;
614
615   if (shndx >= this->shnum())
616     file->error(_("section_info: bad shndx %u >= %u"),
617                 shndx, this->shnum());
618
619   typename File::View v(file->view(this->section_header_offset(shndx),
620                                    This::shdr_size));
621
622   Ef_shdr shdr(v.data());
623   return shdr.get_sh_info();
624 }
625
626 // Return the sh_addralign field of section SHNDX.
627
628 template<int size, bool big_endian, typename File>
629 typename Elf_types<size>::Elf_WXword
630 Elf_file<size, big_endian, File>::section_addralign(unsigned int shndx)
631 {
632   File* const file = this->file_;
633
634   if (shndx >= this->shnum())
635     file->error(_("section_addralign: bad shndx %u >= %u"),
636                 shndx, this->shnum());
637
638   typename File::View v(file->view(this->section_header_offset(shndx),
639                                    This::shdr_size));
640
641   Ef_shdr shdr(v.data());
642   return shdr.get_sh_addralign();
643 }
644
645 } // End namespace elfcpp.
646
647 #endif // !defined(ELFCPP_FILE_H)