1// elfcpp_file.h -- file access for elfcpp -*- C++ -*- 2 3// Copyright (C) 2006-2017 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#include "elfcpp.h" 64 65namespace elfcpp 66{ 67 68// A simple helper class to recognize if a file has an ELF header. 69 70class 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 102template<int size, bool big_endian, typename File> 103class 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 266class 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 294inline bool 295Elf_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 308namespace 309{ 310 311// Print a number to a string. 312 313inline std::string 314internal_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 325inline bool 326Elf_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 403template<int size, bool big_endian, typename File> 404void 405Elf_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 422template<int size, bool big_endian, typename File> 423inline 424Elf_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 432template<int size, bool big_endian, typename File> 433void 434Elf_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 478template<int size, bool big_endian, typename File> 479unsigned int 480Elf_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 496template<int size, bool big_endian, typename File> 497off_t 498Elf_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 508template<int size, bool big_endian, typename File> 509std::string 510Elf_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 555template<int size, bool big_endian, typename File> 556typename File::Location 557Elf_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 573template<int size, bool big_endian, typename File> 574typename Elf_types<size>::Elf_WXword 575Elf_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 592template<int size, bool big_endian, typename File> 593typename Elf_types<size>::Elf_WXword 594Elf_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 611template<int size, bool big_endian, typename File> 612typename Elf_types<size>::Elf_Addr 613Elf_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 630template<int size, bool big_endian, typename File> 631Elf_Word 632Elf_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 649template<int size, bool big_endian, typename File> 650Elf_Word 651Elf_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 668template<int size, bool big_endian, typename File> 669Elf_Word 670Elf_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 687template<int size, bool big_endian, typename File> 688typename Elf_types<size>::Elf_WXword 689Elf_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 704inline 705Elf_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