elfcpp_file.h 20 KB

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