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