ehframe.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. // ehframe.h -- handle exception frame sections for gold -*- 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 gold.
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 3 of the License, or
  8. // (at your option) any later version.
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  16. // MA 02110-1301, USA.
  17. #ifndef GOLD_EHFRAME_H
  18. #define GOLD_EHFRAME_H
  19. #include <map>
  20. #include <set>
  21. #include <vector>
  22. #include "output.h"
  23. #include "merge.h"
  24. namespace gold
  25. {
  26. template<int size, bool big_endian>
  27. class Track_relocs;
  28. class Eh_frame;
  29. // This class manages the .eh_frame_hdr section, which holds the data
  30. // for the PT_GNU_EH_FRAME segment. gcc's unwind support code uses
  31. // the PT_GNU_EH_FRAME segment to find the list of FDEs. This saves
  32. // the time required to register the exception handlers at startup
  33. // time and when a shared object is loaded, and the time required to
  34. // deregister the exception handlers when a shared object is unloaded.
  35. class Eh_frame_hdr : public Output_section_data
  36. {
  37. public:
  38. Eh_frame_hdr(Output_section* eh_frame_section, const Eh_frame*);
  39. // Record that we found an unrecognized .eh_frame section.
  40. void
  41. found_unrecognized_eh_frame_section()
  42. { this->any_unrecognized_eh_frame_sections_ = true; }
  43. // Record an FDE.
  44. void
  45. record_fde(section_offset_type fde_offset, unsigned char fde_encoding)
  46. {
  47. if (!this->any_unrecognized_eh_frame_sections_)
  48. this->fde_offsets_.push_back(std::make_pair(fde_offset, fde_encoding));
  49. }
  50. protected:
  51. // Set the final data size.
  52. void
  53. set_final_data_size();
  54. // Write the data to the file.
  55. void
  56. do_write(Output_file*);
  57. // Write to a map file.
  58. void
  59. do_print_to_mapfile(Mapfile* mapfile) const
  60. { mapfile->print_output_data(this, _("** eh_frame_hdr")); }
  61. private:
  62. // Write the data to the file with the right endianness.
  63. template<int size, bool big_endian>
  64. void
  65. do_sized_write(Output_file*);
  66. // The data we record for one FDE: the offset of the FDE within the
  67. // .eh_frame section, and the FDE encoding.
  68. typedef std::pair<section_offset_type, unsigned char> Fde_offset;
  69. // The list of information we record for an FDE.
  70. typedef std::vector<Fde_offset> Fde_offsets;
  71. // When writing out the header, we convert the FDE offsets into FDE
  72. // addresses. This is a list of pairs of the offset from the header
  73. // to the FDE PC and to the FDE itself.
  74. template<int size>
  75. class Fde_addresses
  76. {
  77. public:
  78. typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  79. typedef typename std::pair<Address, Address> Fde_address;
  80. typedef typename std::vector<Fde_address> Fde_address_list;
  81. typedef typename Fde_address_list::iterator iterator;
  82. Fde_addresses(unsigned int reserve)
  83. : fde_addresses_()
  84. { this->fde_addresses_.reserve(reserve); }
  85. void
  86. push_back(Address pc_address, Address fde_address)
  87. {
  88. this->fde_addresses_.push_back(std::make_pair(pc_address, fde_address));
  89. }
  90. iterator
  91. begin()
  92. { return this->fde_addresses_.begin(); }
  93. iterator
  94. end()
  95. { return this->fde_addresses_.end(); }
  96. private:
  97. Fde_address_list fde_addresses_;
  98. };
  99. // Compare Fde_address objects.
  100. template<int size>
  101. struct Fde_address_compare
  102. {
  103. bool
  104. operator()(const typename Fde_addresses<size>::Fde_address& f1,
  105. const typename Fde_addresses<size>::Fde_address& f2) const
  106. { return f1.first < f2.first; }
  107. };
  108. // Return the PC to which an FDE refers.
  109. template<int size, bool big_endian>
  110. typename elfcpp::Elf_types<size>::Elf_Addr
  111. get_fde_pc(typename elfcpp::Elf_types<size>::Elf_Addr eh_frame_address,
  112. const unsigned char* eh_frame_contents,
  113. section_offset_type fde_offset, unsigned char fde_encoding);
  114. // Convert Fde_offsets to Fde_addresses.
  115. template<int size, bool big_endian>
  116. void
  117. get_fde_addresses(Output_file* of,
  118. const Fde_offsets* fde_offsets,
  119. Fde_addresses<size>* fde_addresses);
  120. // The .eh_frame section.
  121. Output_section* eh_frame_section_;
  122. // The .eh_frame section data.
  123. const Eh_frame* eh_frame_data_;
  124. // Data from the FDEs in the .eh_frame sections.
  125. Fde_offsets fde_offsets_;
  126. // Whether we found any .eh_frame sections which we could not
  127. // process.
  128. bool any_unrecognized_eh_frame_sections_;
  129. };
  130. // This class holds an FDE.
  131. class Fde
  132. {
  133. public:
  134. Fde(Relobj* object, unsigned int shndx, section_offset_type input_offset,
  135. const unsigned char* contents, size_t length)
  136. : object_(object),
  137. contents_(reinterpret_cast<const char*>(contents), length)
  138. {
  139. this->u_.from_object.shndx = shndx;
  140. this->u_.from_object.input_offset = input_offset;
  141. }
  142. // Create an FDE associated with a PLT.
  143. Fde(Output_data* plt, const unsigned char* contents, size_t length,
  144. bool post_map)
  145. : object_(NULL),
  146. contents_(reinterpret_cast<const char*>(contents), length)
  147. {
  148. this->u_.from_linker.plt = plt;
  149. this->u_.from_linker.post_map = post_map;
  150. }
  151. // Return the length of this FDE. Add 4 for the length and 4 for
  152. // the offset to the CIE.
  153. size_t
  154. length() const
  155. { return this->contents_.length() + 8; }
  156. // Add a mapping for this FDE to MERGE_MAP, so that relocations
  157. // against the FDE are applied to right part of the output file.
  158. void
  159. add_mapping(section_offset_type output_offset,
  160. Output_section_data* output_data) const
  161. {
  162. if (this->object_ != NULL)
  163. this->object_->add_merge_mapping(output_data, this->u_.from_object.shndx,
  164. this->u_.from_object.input_offset, this->length(),
  165. output_offset);
  166. }
  167. // Return whether this FDE was added after merge mapping.
  168. bool
  169. post_map()
  170. { return this->object_ == NULL && this->u_.from_linker.post_map; }
  171. // Write the FDE to OVIEW starting at OFFSET. FDE_ENCODING is the
  172. // encoding, from the CIE. Round up the bytes to ADDRALIGN if
  173. // necessary. ADDRESS is the virtual address of OVIEW. Record the
  174. // FDE in EH_FRAME_HDR. Return the new offset.
  175. template<int size, bool big_endian>
  176. section_offset_type
  177. write(unsigned char* oview, section_offset_type output_section_offset,
  178. section_offset_type offset, uint64_t address, unsigned int addralign,
  179. section_offset_type cie_offset, unsigned char fde_encoding,
  180. Eh_frame_hdr* eh_frame_hdr);
  181. private:
  182. // The object in which this FDE was seen. This will be NULL for a
  183. // linker generated FDE.
  184. Relobj* object_;
  185. union
  186. {
  187. // These fields are used if the FDE is from an input object (the
  188. // object_ field is not NULL).
  189. struct
  190. {
  191. // Input section index for this FDE.
  192. unsigned int shndx;
  193. // Offset within the input section for this FDE.
  194. section_offset_type input_offset;
  195. } from_object;
  196. // This field is used if the FDE is generated by the linker (the
  197. // object_ field is NULL).
  198. struct
  199. {
  200. // The only linker generated FDEs are for PLT sections, and this
  201. // points to the PLT section.
  202. Output_data* plt;
  203. // Set if the FDE was added after merge mapping.
  204. bool post_map;
  205. } from_linker;
  206. } u_;
  207. // FDE data.
  208. std::string contents_;
  209. };
  210. // A FDE plus some info from a CIE to allow later writing of the FDE.
  211. struct Post_fde
  212. {
  213. Post_fde(Fde* f, section_offset_type cie_off, unsigned char encoding)
  214. : fde(f), cie_offset(cie_off), fde_encoding(encoding)
  215. { }
  216. Fde* fde;
  217. section_offset_type cie_offset;
  218. unsigned char fde_encoding;
  219. };
  220. typedef std::vector<Post_fde> Post_fdes;
  221. // This class holds a CIE.
  222. class Cie
  223. {
  224. public:
  225. Cie(Relobj* object, unsigned int shndx, section_offset_type input_offset,
  226. unsigned char fde_encoding, const char* personality_name,
  227. const unsigned char* contents, size_t length)
  228. : object_(object),
  229. shndx_(shndx),
  230. input_offset_(input_offset),
  231. fde_encoding_(fde_encoding),
  232. personality_name_(personality_name),
  233. fdes_(),
  234. contents_(reinterpret_cast<const char*>(contents), length)
  235. { }
  236. ~Cie();
  237. // We permit copying a CIE when there are no FDEs. This is
  238. // convenient in the code which creates them.
  239. Cie(const Cie& cie)
  240. : object_(cie.object_),
  241. shndx_(cie.shndx_),
  242. input_offset_(cie.input_offset_),
  243. fde_encoding_(cie.fde_encoding_),
  244. personality_name_(cie.personality_name_),
  245. fdes_(),
  246. contents_(cie.contents_)
  247. { gold_assert(cie.fdes_.empty()); }
  248. // Add an FDE associated with this CIE.
  249. void
  250. add_fde(Fde* fde)
  251. { this->fdes_.push_back(fde); }
  252. // Return the number of FDEs.
  253. unsigned int
  254. fde_count() const
  255. { return this->fdes_.size(); }
  256. // Set the output offset of this CIE to OUTPUT_OFFSET. It will be
  257. // followed by all its FDEs. ADDRALIGN is the required address
  258. // alignment, typically 4 or 8. This updates MERGE_MAP with the
  259. // mapping. It returns the new output offset.
  260. section_offset_type
  261. set_output_offset(section_offset_type output_offset, unsigned int addralign,
  262. Output_section_data*);
  263. // Write the CIE to OVIEW starting at OFFSET. Round up the bytes to
  264. // ADDRALIGN. ADDRESS is the virtual address of OVIEW.
  265. // EH_FRAME_HDR is the exception frame header for FDE recording.
  266. // POST_FDES stashes FDEs created after mappings were done, for later
  267. // writing. Return the new offset.
  268. template<int size, bool big_endian>
  269. section_offset_type
  270. write(unsigned char* oview, section_offset_type output_section_offset,
  271. section_offset_type offset, uint64_t address,
  272. unsigned int addralign, Eh_frame_hdr* eh_frame_hdr,
  273. Post_fdes* post_fdes);
  274. friend bool operator<(const Cie&, const Cie&);
  275. friend bool operator==(const Cie&, const Cie&);
  276. private:
  277. // The class is not assignable.
  278. Cie& operator=(const Cie&);
  279. // The object in which this CIE was first seen. This will be NULL
  280. // for a linker generated CIE.
  281. Relobj* object_;
  282. // Input section index for this CIE. This will be 0 for a linker
  283. // generated CIE.
  284. unsigned int shndx_;
  285. // Offset within the input section for this CIE. This will be 0 for
  286. // a linker generated CIE.
  287. section_offset_type input_offset_;
  288. // The encoding of the FDE. This is a DW_EH_PE code.
  289. unsigned char fde_encoding_;
  290. // The name of the personality routine. This will be the name of a
  291. // global symbol, or will be the empty string.
  292. std::string personality_name_;
  293. // List of FDEs.
  294. std::vector<Fde*> fdes_;
  295. // CIE data.
  296. std::string contents_;
  297. };
  298. extern bool operator<(const Cie&, const Cie&);
  299. extern bool operator==(const Cie&, const Cie&);
  300. // This class manages .eh_frame sections. It discards duplicate
  301. // exception information.
  302. class Eh_frame : public Output_section_data
  303. {
  304. public:
  305. enum Eh_frame_section_disposition
  306. {
  307. EH_EMPTY_SECTION,
  308. EH_UNRECOGNIZED_SECTION,
  309. EH_OPTIMIZABLE_SECTION,
  310. EH_END_MARKER_SECTION
  311. };
  312. Eh_frame();
  313. // Record the associated Eh_frame_hdr, if any.
  314. void
  315. set_eh_frame_hdr(Eh_frame_hdr* hdr)
  316. { this->eh_frame_hdr_ = hdr; }
  317. // Add the input section SHNDX in OBJECT. SYMBOLS is the contents
  318. // of the symbol table section (size SYMBOLS_SIZE), SYMBOL_NAMES is
  319. // the symbol names section (size SYMBOL_NAMES_SIZE). RELOC_SHNDX
  320. // is the relocation section if any (0 for none, -1U for multiple).
  321. // RELOC_TYPE is the type of the relocation section if any. This
  322. // returns whether the section was incorporated into the .eh_frame
  323. // data.
  324. template<int size, bool big_endian>
  325. Eh_frame_section_disposition
  326. add_ehframe_input_section(Sized_relobj_file<size, big_endian>* object,
  327. const unsigned char* symbols,
  328. section_size_type symbols_size,
  329. const unsigned char* symbol_names,
  330. section_size_type symbol_names_size,
  331. unsigned int shndx, unsigned int reloc_shndx,
  332. unsigned int reloc_type);
  333. // Add a CIE and an FDE for a PLT section, to permit unwinding
  334. // through a PLT. The FDE data should start with 8 bytes of zero,
  335. // which will be replaced by a 4 byte PC relative reference to the
  336. // address of PLT and a 4 byte size of PLT.
  337. void
  338. add_ehframe_for_plt(Output_data* plt, const unsigned char* cie_data,
  339. size_t cie_length, const unsigned char* fde_data,
  340. size_t fde_length);
  341. // Return the number of FDEs.
  342. unsigned int
  343. fde_count() const;
  344. protected:
  345. // Set the final data size.
  346. void
  347. set_final_data_size();
  348. // Return the output address for an input address.
  349. bool
  350. do_output_offset(const Relobj*, unsigned int shndx,
  351. section_offset_type offset,
  352. section_offset_type* poutput) const;
  353. // Write the data to the file.
  354. void
  355. do_write(Output_file*);
  356. // Write to a map file.
  357. void
  358. do_print_to_mapfile(Mapfile* mapfile) const
  359. { mapfile->print_output_data(this, _("** eh_frame")); }
  360. private:
  361. // The comparison routine for the CIE map.
  362. struct Cie_less
  363. {
  364. bool
  365. operator()(const Cie* cie1, const Cie* cie2) const
  366. { return *cie1 < *cie2; }
  367. };
  368. // A set of unique CIEs.
  369. typedef std::set<Cie*, Cie_less> Cie_offsets;
  370. // A list of unmergeable CIEs.
  371. typedef std::vector<Cie*> Unmergeable_cie_offsets;
  372. // A mapping from offsets to CIEs. This is used while reading an
  373. // input section.
  374. typedef std::map<uint64_t, Cie*> Offsets_to_cie;
  375. // A list of CIEs, and a bool indicating whether the CIE is
  376. // mergeable.
  377. typedef std::vector<std::pair<Cie*, bool> > New_cies;
  378. // Skip an LEB128.
  379. static bool
  380. skip_leb128(const unsigned char**, const unsigned char*);
  381. // The implementation of add_ehframe_input_section.
  382. template<int size, bool big_endian>
  383. bool
  384. do_add_ehframe_input_section(Sized_relobj_file<size, big_endian>* object,
  385. const unsigned char* symbols,
  386. section_size_type symbols_size,
  387. const unsigned char* symbol_names,
  388. section_size_type symbol_names_size,
  389. unsigned int shndx,
  390. unsigned int reloc_shndx,
  391. unsigned int reloc_type,
  392. const unsigned char* pcontents,
  393. section_size_type contents_len,
  394. New_cies*);
  395. // Read a CIE.
  396. template<int size, bool big_endian>
  397. bool
  398. read_cie(Sized_relobj_file<size, big_endian>* object,
  399. unsigned int shndx,
  400. const unsigned char* symbols,
  401. section_size_type symbols_size,
  402. const unsigned char* symbol_names,
  403. section_size_type symbol_names_size,
  404. const unsigned char* pcontents,
  405. const unsigned char* pcie,
  406. const unsigned char* pcieend,
  407. Track_relocs<size, big_endian>* relocs,
  408. Offsets_to_cie* cies,
  409. New_cies* new_cies);
  410. // Read an FDE.
  411. template<int size, bool big_endian>
  412. bool
  413. read_fde(Sized_relobj_file<size, big_endian>* object,
  414. unsigned int shndx,
  415. const unsigned char* symbols,
  416. section_size_type symbols_size,
  417. const unsigned char* pcontents,
  418. unsigned int offset,
  419. const unsigned char* pfde,
  420. const unsigned char* pfdeend,
  421. Track_relocs<size, big_endian>* relocs,
  422. Offsets_to_cie* cies);
  423. // Template version of write function.
  424. template<int size, bool big_endian>
  425. void
  426. do_sized_write(unsigned char* oview);
  427. // The exception frame header, if any.
  428. Eh_frame_hdr* eh_frame_hdr_;
  429. // A mapping from all unique CIEs to their offset in the output
  430. // file.
  431. Cie_offsets cie_offsets_;
  432. // A mapping from unmergeable CIEs to their offset in the output
  433. // file.
  434. Unmergeable_cie_offsets unmergeable_cie_offsets_;
  435. // Whether we have created the mappings to the output section.
  436. bool mappings_are_done_;
  437. // The final data size. This is only set if mappings_are_done_ is
  438. // true.
  439. section_size_type final_data_size_;
  440. };
  441. } // End namespace gold.
  442. #endif // !defined(GOLD_EHFRAME_H)