ehframe.cc 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369
  1. // ehframe.cc -- handle exception frame sections for gold
  2. // Copyright (C) 2006-2022 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. #include "gold.h"
  18. #include <cstring>
  19. #include <algorithm>
  20. #include "elfcpp.h"
  21. #include "dwarf.h"
  22. #include "symtab.h"
  23. #include "reloc.h"
  24. #include "ehframe.h"
  25. namespace gold
  26. {
  27. // This file handles generation of the exception frame header that
  28. // gcc's runtime support libraries use to find unwind information at
  29. // runtime. This file also handles discarding duplicate exception
  30. // frame information.
  31. // The exception frame header starts with four bytes:
  32. // 0: The version number, currently 1.
  33. // 1: The encoding of the pointer to the exception frames. This can
  34. // be any DWARF unwind encoding (DW_EH_PE_*). It is normally a 4
  35. // byte PC relative offset (DW_EH_PE_pcrel | DW_EH_PE_sdata4).
  36. // 2: The encoding of the count of the number of FDE pointers in the
  37. // lookup table. This can be any DWARF unwind encoding, and in
  38. // particular can be DW_EH_PE_omit if the count is omitted. It is
  39. // normally a 4 byte unsigned count (DW_EH_PE_udata4).
  40. // 3: The encoding of the lookup table entries. Currently gcc's
  41. // libraries will only support DW_EH_PE_datarel | DW_EH_PE_sdata4,
  42. // which means that the values are 4 byte offsets from the start of
  43. // the table.
  44. // The exception frame header is followed by a pointer to the contents
  45. // of the exception frame section (.eh_frame). This pointer is
  46. // encoded as specified in the byte at offset 1 of the header (i.e.,
  47. // it is normally a 4 byte PC relative offset).
  48. // If there is a lookup table, this is followed by the count of the
  49. // number of FDE pointers, encoded as specified in the byte at offset
  50. // 2 of the header (i.e., normally a 4 byte unsigned integer).
  51. // This is followed by the table, which should start at an 4-byte
  52. // aligned address in memory. Each entry in the table is 8 bytes.
  53. // Each entry represents an FDE. The first four bytes of each entry
  54. // are an offset to the starting PC for the FDE. The last four bytes
  55. // of each entry are an offset to the FDE data. The offsets are from
  56. // the start of the exception frame header information. The entries
  57. // are in sorted order by starting PC.
  58. const int eh_frame_hdr_size = 4;
  59. // Construct the exception frame header.
  60. Eh_frame_hdr::Eh_frame_hdr(Output_section* eh_frame_section,
  61. const Eh_frame* eh_frame_data)
  62. : Output_section_data(4),
  63. eh_frame_section_(eh_frame_section),
  64. eh_frame_data_(eh_frame_data),
  65. fde_offsets_(),
  66. any_unrecognized_eh_frame_sections_(false)
  67. {
  68. }
  69. // Set the size of the exception frame header.
  70. void
  71. Eh_frame_hdr::set_final_data_size()
  72. {
  73. unsigned int data_size = eh_frame_hdr_size + 4;
  74. if (!this->any_unrecognized_eh_frame_sections_)
  75. {
  76. unsigned int fde_count = this->eh_frame_data_->fde_count();
  77. if (fde_count != 0)
  78. data_size += 4 + 8 * fde_count;
  79. this->fde_offsets_.reserve(fde_count);
  80. }
  81. this->set_data_size(data_size);
  82. }
  83. // Write the data to the file.
  84. void
  85. Eh_frame_hdr::do_write(Output_file* of)
  86. {
  87. switch (parameters->size_and_endianness())
  88. {
  89. #ifdef HAVE_TARGET_32_LITTLE
  90. case Parameters::TARGET_32_LITTLE:
  91. this->do_sized_write<32, false>(of);
  92. break;
  93. #endif
  94. #ifdef HAVE_TARGET_32_BIG
  95. case Parameters::TARGET_32_BIG:
  96. this->do_sized_write<32, true>(of);
  97. break;
  98. #endif
  99. #ifdef HAVE_TARGET_64_LITTLE
  100. case Parameters::TARGET_64_LITTLE:
  101. this->do_sized_write<64, false>(of);
  102. break;
  103. #endif
  104. #ifdef HAVE_TARGET_64_BIG
  105. case Parameters::TARGET_64_BIG:
  106. this->do_sized_write<64, true>(of);
  107. break;
  108. #endif
  109. default:
  110. gold_unreachable();
  111. }
  112. }
  113. // Write the data to the file with the right endianness.
  114. template<int size, bool big_endian>
  115. void
  116. Eh_frame_hdr::do_sized_write(Output_file* of)
  117. {
  118. const off_t off = this->offset();
  119. const off_t oview_size = this->data_size();
  120. unsigned char* const oview = of->get_output_view(off, oview_size);
  121. // Version number.
  122. oview[0] = 1;
  123. // Write out a 4 byte PC relative offset to the address of the
  124. // .eh_frame section.
  125. oview[1] = elfcpp::DW_EH_PE_pcrel | elfcpp::DW_EH_PE_sdata4;
  126. uint64_t eh_frame_address = this->eh_frame_section_->address();
  127. uint64_t eh_frame_hdr_address = this->address();
  128. uint64_t eh_frame_offset = (eh_frame_address -
  129. (eh_frame_hdr_address + 4));
  130. elfcpp::Swap<32, big_endian>::writeval(oview + 4, eh_frame_offset);
  131. if (this->any_unrecognized_eh_frame_sections_
  132. || this->fde_offsets_.empty())
  133. {
  134. // There are no FDEs, or we didn't recognize the format of the
  135. // some of the .eh_frame sections, so we can't write out the
  136. // sorted table.
  137. oview[2] = elfcpp::DW_EH_PE_omit;
  138. oview[3] = elfcpp::DW_EH_PE_omit;
  139. gold_assert(oview_size == 8);
  140. }
  141. else
  142. {
  143. oview[2] = elfcpp::DW_EH_PE_udata4;
  144. oview[3] = elfcpp::DW_EH_PE_datarel | elfcpp::DW_EH_PE_sdata4;
  145. elfcpp::Swap<32, big_endian>::writeval(oview + 8,
  146. this->fde_offsets_.size());
  147. // We have the offsets of the FDEs in the .eh_frame section. We
  148. // couldn't easily get the PC values before, as they depend on
  149. // relocations which are, of course, target specific. This code
  150. // is run after all those relocations have been applied to the
  151. // output file. Here we read the output file again to find the
  152. // PC values. Then we sort the list and write it out.
  153. Fde_addresses<size> fde_addresses(this->fde_offsets_.size());
  154. this->get_fde_addresses<size, big_endian>(of, &this->fde_offsets_,
  155. &fde_addresses);
  156. std::sort(fde_addresses.begin(), fde_addresses.end(),
  157. Fde_address_compare<size>());
  158. typename elfcpp::Elf_types<size>::Elf_Addr output_address;
  159. output_address = this->address();
  160. unsigned char* pfde = oview + 12;
  161. for (typename Fde_addresses<size>::iterator p = fde_addresses.begin();
  162. p != fde_addresses.end();
  163. ++p)
  164. {
  165. elfcpp::Swap<32, big_endian>::writeval(pfde,
  166. p->first - output_address);
  167. elfcpp::Swap<32, big_endian>::writeval(pfde + 4,
  168. p->second - output_address);
  169. pfde += 8;
  170. }
  171. gold_assert(pfde - oview == oview_size);
  172. }
  173. of->write_output_view(off, oview_size, oview);
  174. }
  175. // Given the offset FDE_OFFSET of an FDE in the .eh_frame section, and
  176. // the contents of the .eh_frame section EH_FRAME_CONTENTS, where the
  177. // FDE's encoding is FDE_ENCODING, return the output address of the
  178. // FDE's PC.
  179. template<int size, bool big_endian>
  180. typename elfcpp::Elf_types<size>::Elf_Addr
  181. Eh_frame_hdr::get_fde_pc(
  182. typename elfcpp::Elf_types<size>::Elf_Addr eh_frame_address,
  183. const unsigned char* eh_frame_contents,
  184. section_offset_type fde_offset,
  185. unsigned char fde_encoding)
  186. {
  187. // The FDE starts with a 4 byte length and a 4 byte offset to the
  188. // CIE. The PC follows.
  189. const unsigned char* p = eh_frame_contents + fde_offset + 8;
  190. typename elfcpp::Elf_types<size>::Elf_Addr pc;
  191. bool is_signed = (fde_encoding & elfcpp::DW_EH_PE_signed) != 0;
  192. int pc_size = fde_encoding & 7;
  193. if (pc_size == elfcpp::DW_EH_PE_absptr)
  194. {
  195. if (size == 32)
  196. pc_size = elfcpp::DW_EH_PE_udata4;
  197. else if (size == 64)
  198. pc_size = elfcpp::DW_EH_PE_udata8;
  199. else
  200. gold_unreachable();
  201. }
  202. switch (pc_size)
  203. {
  204. case elfcpp::DW_EH_PE_udata2:
  205. pc = elfcpp::Swap<16, big_endian>::readval(p);
  206. if (is_signed)
  207. pc = (pc ^ 0x8000) - 0x8000;
  208. break;
  209. case elfcpp::DW_EH_PE_udata4:
  210. pc = elfcpp::Swap<32, big_endian>::readval(p);
  211. if (size > 32 && is_signed)
  212. pc = (pc ^ 0x80000000) - 0x80000000;
  213. break;
  214. case elfcpp::DW_EH_PE_udata8:
  215. gold_assert(size == 64);
  216. pc = elfcpp::Swap_unaligned<64, big_endian>::readval(p);
  217. break;
  218. default:
  219. // All other cases were rejected in Eh_frame::read_cie.
  220. gold_unreachable();
  221. }
  222. switch (fde_encoding & 0x70)
  223. {
  224. case 0:
  225. break;
  226. case elfcpp::DW_EH_PE_pcrel:
  227. pc += eh_frame_address + fde_offset + 8;
  228. break;
  229. case elfcpp::DW_EH_PE_datarel:
  230. pc += parameters->target().ehframe_datarel_base();
  231. break;
  232. default:
  233. // If other cases arise, then we have to handle them, or we have
  234. // to reject them by returning false in Eh_frame::read_cie.
  235. gold_unreachable();
  236. }
  237. gold_assert((fde_encoding & elfcpp::DW_EH_PE_indirect) == 0);
  238. return pc;
  239. }
  240. // Given an array of FDE offsets in the .eh_frame section, return an
  241. // array of offsets from the exception frame header to the FDE's
  242. // output PC and to the output address of the FDE itself. We get the
  243. // FDE's PC by actually looking in the .eh_frame section we just wrote
  244. // to the output file.
  245. template<int size, bool big_endian>
  246. void
  247. Eh_frame_hdr::get_fde_addresses(Output_file* of,
  248. const Fde_offsets* fde_offsets,
  249. Fde_addresses<size>* fde_addresses)
  250. {
  251. typename elfcpp::Elf_types<size>::Elf_Addr eh_frame_address;
  252. eh_frame_address = this->eh_frame_section_->address();
  253. off_t eh_frame_offset = this->eh_frame_section_->offset();
  254. off_t eh_frame_size = this->eh_frame_section_->data_size();
  255. const unsigned char* eh_frame_contents = of->get_input_view(eh_frame_offset,
  256. eh_frame_size);
  257. for (Fde_offsets::const_iterator p = fde_offsets->begin();
  258. p != fde_offsets->end();
  259. ++p)
  260. {
  261. typename elfcpp::Elf_types<size>::Elf_Addr fde_pc;
  262. fde_pc = this->get_fde_pc<size, big_endian>(eh_frame_address,
  263. eh_frame_contents,
  264. p->first, p->second);
  265. fde_addresses->push_back(fde_pc, eh_frame_address + p->first);
  266. }
  267. of->free_input_view(eh_frame_offset, eh_frame_size, eh_frame_contents);
  268. }
  269. // Class Fde.
  270. // Write the FDE to OVIEW starting at OFFSET. CIE_OFFSET is the
  271. // offset of the CIE in OVIEW. OUTPUT_OFFSET is the offset of the
  272. // Eh_frame section within the output section. FDE_ENCODING is the
  273. // encoding, from the CIE. ADDRALIGN is the required alignment.
  274. // ADDRESS is the virtual address of OVIEW. Record the FDE pc for
  275. // EH_FRAME_HDR. Return the new offset.
  276. template<int size, bool big_endian>
  277. section_offset_type
  278. Fde::write(unsigned char* oview, section_offset_type output_offset,
  279. section_offset_type offset, uint64_t address, unsigned int addralign,
  280. section_offset_type cie_offset, unsigned char fde_encoding,
  281. Eh_frame_hdr* eh_frame_hdr)
  282. {
  283. gold_assert((offset & (addralign - 1)) == 0);
  284. size_t length = this->contents_.length();
  285. // We add 8 when getting the aligned length to account for the
  286. // length word and the CIE offset.
  287. size_t aligned_full_length = align_address(length + 8, addralign);
  288. // Write the length of the FDE as a 32-bit word. The length word
  289. // does not include the four bytes of the length word itself, but it
  290. // does include the offset to the CIE.
  291. elfcpp::Swap<32, big_endian>::writeval(oview + offset,
  292. aligned_full_length - 4);
  293. // Write the offset to the CIE as a 32-bit word. This is the
  294. // difference between the address of the offset word itself and the
  295. // CIE address.
  296. elfcpp::Swap<32, big_endian>::writeval(oview + offset + 4,
  297. offset + 4 - cie_offset);
  298. // Copy the rest of the FDE. Note that this is run before
  299. // relocation processing is done on this section, so the relocations
  300. // will later be applied to the FDE data.
  301. memcpy(oview + offset + 8, this->contents_.data(), length);
  302. // If this FDE is associated with a PLT, fill in the PLT's address
  303. // and size.
  304. if (this->object_ == NULL)
  305. {
  306. gold_assert(memcmp(oview + offset + 8, "\0\0\0\0\0\0\0\0", 8) == 0);
  307. uint64_t paddress;
  308. off_t psize;
  309. parameters->target().plt_fde_location(this->u_.from_linker.plt,
  310. oview + offset + 8,
  311. &paddress, &psize);
  312. uint64_t poffset = paddress - (address + offset + 8);
  313. int32_t spoffset = static_cast<int32_t>(poffset);
  314. uint32_t upsize = static_cast<uint32_t>(psize);
  315. if (static_cast<uint64_t>(static_cast<int64_t>(spoffset)) != poffset
  316. || static_cast<off_t>(upsize) != psize)
  317. gold_warning(_("overflow in PLT unwind data; "
  318. "unwinding through PLT may fail"));
  319. elfcpp::Swap<32, big_endian>::writeval(oview + offset + 8, spoffset);
  320. elfcpp::Swap<32, big_endian>::writeval(oview + offset + 12, upsize);
  321. }
  322. if (aligned_full_length > length + 8)
  323. memset(oview + offset + length + 8, 0, aligned_full_length - (length + 8));
  324. // Tell the exception frame header about this FDE.
  325. if (eh_frame_hdr != NULL)
  326. eh_frame_hdr->record_fde(output_offset + offset, fde_encoding);
  327. return offset + aligned_full_length;
  328. }
  329. // Class Cie.
  330. // Destructor.
  331. Cie::~Cie()
  332. {
  333. for (std::vector<Fde*>::iterator p = this->fdes_.begin();
  334. p != this->fdes_.end();
  335. ++p)
  336. delete *p;
  337. }
  338. // Set the output offset of a CIE. Return the new output offset.
  339. section_offset_type
  340. Cie::set_output_offset(section_offset_type output_offset,
  341. unsigned int addralign,
  342. Output_section_data *output_data)
  343. {
  344. size_t length = this->contents_.length();
  345. // Add 4 for length and 4 for zero CIE identifier tag.
  346. length += 8;
  347. if (this->object_ != NULL)
  348. {
  349. // Add a mapping so that relocations are applied correctly.
  350. this->object_->add_merge_mapping(output_data, this->shndx_,
  351. this->input_offset_, length,
  352. output_offset);
  353. }
  354. length = align_address(length, addralign);
  355. for (std::vector<Fde*>::const_iterator p = this->fdes_.begin();
  356. p != this->fdes_.end();
  357. ++p)
  358. {
  359. (*p)->add_mapping(output_offset + length, output_data);
  360. size_t fde_length = (*p)->length();
  361. fde_length = align_address(fde_length, addralign);
  362. length += fde_length;
  363. }
  364. return output_offset + length;
  365. }
  366. // Write the CIE to OVIEW starting at OFFSET. OUTPUT_OFFSET is the
  367. // offset of the Eh_frame section within the output section. Round up
  368. // the bytes to ADDRALIGN. ADDRESS is the virtual address of OVIEW.
  369. // EH_FRAME_HDR is the exception frame header for FDE recording.
  370. // POST_FDES stashes FDEs created after mappings were done, for later
  371. // writing. Return the new offset.
  372. template<int size, bool big_endian>
  373. section_offset_type
  374. Cie::write(unsigned char* oview, section_offset_type output_offset,
  375. section_offset_type offset, uint64_t address,
  376. unsigned int addralign, Eh_frame_hdr* eh_frame_hdr,
  377. Post_fdes* post_fdes)
  378. {
  379. gold_assert((offset & (addralign - 1)) == 0);
  380. section_offset_type cie_offset = offset;
  381. size_t length = this->contents_.length();
  382. // We add 8 when getting the aligned length to account for the
  383. // length word and the CIE tag.
  384. size_t aligned_full_length = align_address(length + 8, addralign);
  385. // Write the length of the CIE as a 32-bit word. The length word
  386. // does not include the four bytes of the length word itself.
  387. elfcpp::Swap<32, big_endian>::writeval(oview + offset,
  388. aligned_full_length - 4);
  389. // Write the tag which marks this as a CIE: a 32-bit zero.
  390. elfcpp::Swap<32, big_endian>::writeval(oview + offset + 4, 0);
  391. // Write out the CIE data.
  392. memcpy(oview + offset + 8, this->contents_.data(), length);
  393. if (aligned_full_length > length + 8)
  394. memset(oview + offset + length + 8, 0, aligned_full_length - (length + 8));
  395. offset += aligned_full_length;
  396. // Write out the associated FDEs.
  397. unsigned char fde_encoding = this->fde_encoding_;
  398. for (std::vector<Fde*>::const_iterator p = this->fdes_.begin();
  399. p != this->fdes_.end();
  400. ++p)
  401. {
  402. if ((*p)->post_map())
  403. post_fdes->push_back(Post_fde(*p, cie_offset, fde_encoding));
  404. else
  405. offset = (*p)->write<size, big_endian>(oview, output_offset, offset,
  406. address, addralign, cie_offset,
  407. fde_encoding, eh_frame_hdr);
  408. }
  409. return offset;
  410. }
  411. // We track all the CIEs we see, and merge them when possible. This
  412. // works because each FDE holds an offset to the relevant CIE: we
  413. // rewrite the FDEs to point to the merged CIE. This is worthwhile
  414. // because in a typical C++ program many FDEs in many different object
  415. // files will use the same CIE.
  416. // An equality operator for Cie.
  417. bool
  418. operator==(const Cie& cie1, const Cie& cie2)
  419. {
  420. return (cie1.personality_name_ == cie2.personality_name_
  421. && cie1.contents_ == cie2.contents_);
  422. }
  423. // A less-than operator for Cie.
  424. bool
  425. operator<(const Cie& cie1, const Cie& cie2)
  426. {
  427. if (cie1.personality_name_ != cie2.personality_name_)
  428. return cie1.personality_name_ < cie2.personality_name_;
  429. return cie1.contents_ < cie2.contents_;
  430. }
  431. // Class Eh_frame.
  432. Eh_frame::Eh_frame()
  433. : Output_section_data(Output_data::default_alignment()),
  434. eh_frame_hdr_(NULL),
  435. cie_offsets_(),
  436. unmergeable_cie_offsets_(),
  437. mappings_are_done_(false),
  438. final_data_size_(0)
  439. {
  440. }
  441. // Skip an LEB128, updating *PP to point to the next character.
  442. // Return false if we ran off the end of the string.
  443. bool
  444. Eh_frame::skip_leb128(const unsigned char** pp, const unsigned char* pend)
  445. {
  446. const unsigned char* p;
  447. for (p = *pp; p < pend; ++p)
  448. {
  449. if ((*p & 0x80) == 0)
  450. {
  451. *pp = p + 1;
  452. return true;
  453. }
  454. }
  455. return false;
  456. }
  457. // Add input section SHNDX in OBJECT to an exception frame section.
  458. // SYMBOLS is the contents of the symbol table section (size
  459. // SYMBOLS_SIZE), SYMBOL_NAMES is the symbol names section (size
  460. // SYMBOL_NAMES_SIZE). RELOC_SHNDX is the index of a relocation
  461. // section applying to SHNDX, or 0 if none, or -1U if more than one.
  462. // RELOC_TYPE is the type of the reloc section if there is one, either
  463. // SHT_REL or SHT_RELA. We try to parse the input exception frame
  464. // data into our data structures. If we can't do it, we return false
  465. // to mean that the section should be handled as a normal input
  466. // section.
  467. template<int size, bool big_endian>
  468. Eh_frame::Eh_frame_section_disposition
  469. Eh_frame::add_ehframe_input_section(
  470. Sized_relobj_file<size, big_endian>* object,
  471. const unsigned char* symbols,
  472. section_size_type symbols_size,
  473. const unsigned char* symbol_names,
  474. section_size_type symbol_names_size,
  475. unsigned int shndx,
  476. unsigned int reloc_shndx,
  477. unsigned int reloc_type)
  478. {
  479. // Get the section contents.
  480. section_size_type contents_len;
  481. const unsigned char* pcontents = object->section_contents(shndx,
  482. &contents_len,
  483. false);
  484. if (contents_len == 0)
  485. return EH_EMPTY_SECTION;
  486. // If this is the marker section for the end of the data, then
  487. // return false to force it to be handled as an ordinary input
  488. // section. If we don't do this, we won't correctly handle the case
  489. // of unrecognized .eh_frame sections.
  490. if (contents_len == 4
  491. && elfcpp::Swap<32, big_endian>::readval(pcontents) == 0)
  492. return EH_END_MARKER_SECTION;
  493. New_cies new_cies;
  494. if (!this->do_add_ehframe_input_section(object, symbols, symbols_size,
  495. symbol_names, symbol_names_size,
  496. shndx, reloc_shndx,
  497. reloc_type, pcontents,
  498. contents_len, &new_cies))
  499. {
  500. if (this->eh_frame_hdr_ != NULL)
  501. this->eh_frame_hdr_->found_unrecognized_eh_frame_section();
  502. for (New_cies::iterator p = new_cies.begin();
  503. p != new_cies.end();
  504. ++p)
  505. delete p->first;
  506. return EH_UNRECOGNIZED_SECTION;
  507. }
  508. // Now that we know we are using this section, record any new CIEs
  509. // that we found.
  510. for (New_cies::const_iterator p = new_cies.begin();
  511. p != new_cies.end();
  512. ++p)
  513. {
  514. if (p->second)
  515. this->cie_offsets_.insert(p->first);
  516. else
  517. this->unmergeable_cie_offsets_.push_back(p->first);
  518. }
  519. return EH_OPTIMIZABLE_SECTION;
  520. }
  521. // The bulk of the implementation of add_ehframe_input_section.
  522. template<int size, bool big_endian>
  523. bool
  524. Eh_frame::do_add_ehframe_input_section(
  525. Sized_relobj_file<size, big_endian>* object,
  526. const unsigned char* symbols,
  527. section_size_type symbols_size,
  528. const unsigned char* symbol_names,
  529. section_size_type symbol_names_size,
  530. unsigned int shndx,
  531. unsigned int reloc_shndx,
  532. unsigned int reloc_type,
  533. const unsigned char* pcontents,
  534. section_size_type contents_len,
  535. New_cies* new_cies)
  536. {
  537. Track_relocs<size, big_endian> relocs;
  538. const unsigned char* p = pcontents;
  539. const unsigned char* pend = p + contents_len;
  540. // Get the contents of the reloc section if any.
  541. if (!relocs.initialize(object, reloc_shndx, reloc_type))
  542. return false;
  543. // Keep track of which CIEs are at which offsets.
  544. Offsets_to_cie cies;
  545. while (p < pend)
  546. {
  547. if (pend - p < 4)
  548. return false;
  549. // There shouldn't be any relocations here.
  550. if (relocs.advance(p + 4 - pcontents) > 0)
  551. return false;
  552. unsigned int len = elfcpp::Swap<32, big_endian>::readval(p);
  553. p += 4;
  554. if (len == 0)
  555. {
  556. // We should only find a zero-length entry at the end of the
  557. // section.
  558. if (p < pend)
  559. return false;
  560. break;
  561. }
  562. // We don't support a 64-bit .eh_frame.
  563. if (len == 0xffffffff)
  564. return false;
  565. if (static_cast<unsigned int>(pend - p) < len)
  566. return false;
  567. const unsigned char* const pentend = p + len;
  568. if (pend - p < 4)
  569. return false;
  570. if (relocs.advance(p + 4 - pcontents) > 0)
  571. return false;
  572. unsigned int id = elfcpp::Swap<32, big_endian>::readval(p);
  573. p += 4;
  574. if (id == 0)
  575. {
  576. // CIE.
  577. if (!this->read_cie(object, shndx, symbols, symbols_size,
  578. symbol_names, symbol_names_size,
  579. pcontents, p, pentend, &relocs, &cies,
  580. new_cies))
  581. return false;
  582. }
  583. else
  584. {
  585. // FDE.
  586. if (!this->read_fde(object, shndx, symbols, symbols_size,
  587. pcontents, id, p, pentend, &relocs, &cies))
  588. return false;
  589. }
  590. p = pentend;
  591. }
  592. return true;
  593. }
  594. // Read a CIE. Return false if we can't parse the information.
  595. template<int size, bool big_endian>
  596. bool
  597. Eh_frame::read_cie(Sized_relobj_file<size, big_endian>* object,
  598. unsigned int shndx,
  599. const unsigned char* symbols,
  600. section_size_type symbols_size,
  601. const unsigned char* symbol_names,
  602. section_size_type symbol_names_size,
  603. const unsigned char* pcontents,
  604. const unsigned char* pcie,
  605. const unsigned char* pcieend,
  606. Track_relocs<size, big_endian>* relocs,
  607. Offsets_to_cie* cies,
  608. New_cies* new_cies)
  609. {
  610. bool mergeable = true;
  611. // We need to find the personality routine if there is one, since we
  612. // can only merge CIEs which use the same routine. We also need to
  613. // find the FDE encoding if there is one, so that we can read the PC
  614. // from the FDE.
  615. const unsigned char* p = pcie;
  616. if (pcieend - p < 1)
  617. return false;
  618. unsigned char version = *p++;
  619. if (version != 1 && version != 3)
  620. return false;
  621. const unsigned char* paug = p;
  622. const void* paugendv = memchr(p, '\0', pcieend - p);
  623. const unsigned char* paugend = static_cast<const unsigned char*>(paugendv);
  624. if (paugend == NULL)
  625. return false;
  626. p = paugend + 1;
  627. if (paug[0] == 'e' && paug[1] == 'h')
  628. {
  629. // This is a CIE from gcc before version 3.0. We can't merge
  630. // these. We can still read the FDEs.
  631. mergeable = false;
  632. paug += 2;
  633. if (*paug != '\0')
  634. return false;
  635. if (pcieend - p < size / 8)
  636. return false;
  637. p += size / 8;
  638. }
  639. // Skip the code alignment.
  640. if (!skip_leb128(&p, pcieend))
  641. return false;
  642. // Skip the data alignment.
  643. if (!skip_leb128(&p, pcieend))
  644. return false;
  645. // Skip the return column.
  646. if (version == 1)
  647. {
  648. if (pcieend - p < 1)
  649. return false;
  650. ++p;
  651. }
  652. else
  653. {
  654. if (!skip_leb128(&p, pcieend))
  655. return false;
  656. }
  657. if (*paug == 'z')
  658. {
  659. ++paug;
  660. // Skip the augmentation size.
  661. if (!skip_leb128(&p, pcieend))
  662. return false;
  663. }
  664. unsigned char fde_encoding = elfcpp::DW_EH_PE_absptr;
  665. int per_offset = -1;
  666. while (*paug != '\0')
  667. {
  668. switch (*paug)
  669. {
  670. case 'L': // LSDA encoding.
  671. if (pcieend - p < 1)
  672. return false;
  673. ++p;
  674. break;
  675. case 'R': // FDE encoding.
  676. if (pcieend - p < 1)
  677. return false;
  678. fde_encoding = *p;
  679. switch (fde_encoding & 7)
  680. {
  681. case elfcpp::DW_EH_PE_absptr:
  682. case elfcpp::DW_EH_PE_udata2:
  683. case elfcpp::DW_EH_PE_udata4:
  684. case elfcpp::DW_EH_PE_udata8:
  685. break;
  686. default:
  687. // We don't expect to see any other cases here, and
  688. // we're not prepared to handle them.
  689. return false;
  690. }
  691. ++p;
  692. break;
  693. case 'S':
  694. break;
  695. case 'P':
  696. // Personality encoding.
  697. {
  698. if (pcieend - p < 1)
  699. return false;
  700. unsigned char per_encoding = *p;
  701. ++p;
  702. if ((per_encoding & 0x60) == 0x60)
  703. return false;
  704. unsigned int per_width;
  705. switch (per_encoding & 7)
  706. {
  707. case elfcpp::DW_EH_PE_udata2:
  708. per_width = 2;
  709. break;
  710. case elfcpp::DW_EH_PE_udata4:
  711. per_width = 4;
  712. break;
  713. case elfcpp::DW_EH_PE_udata8:
  714. per_width = 8;
  715. break;
  716. case elfcpp::DW_EH_PE_absptr:
  717. per_width = size / 8;
  718. break;
  719. default:
  720. return false;
  721. }
  722. if ((per_encoding & 0xf0) == elfcpp::DW_EH_PE_aligned)
  723. {
  724. unsigned int len = p - pcie;
  725. len += per_width - 1;
  726. len &= ~ (per_width - 1);
  727. if (static_cast<unsigned int>(pcieend - p) < len)
  728. return false;
  729. p += len;
  730. }
  731. per_offset = p - pcontents;
  732. if (static_cast<unsigned int>(pcieend - p) < per_width)
  733. return false;
  734. p += per_width;
  735. }
  736. break;
  737. default:
  738. return false;
  739. }
  740. ++paug;
  741. }
  742. const char* personality_name = "";
  743. if (per_offset != -1)
  744. {
  745. if (relocs->advance(per_offset) > 0)
  746. return false;
  747. if (relocs->next_offset() != per_offset)
  748. return false;
  749. unsigned int personality_symndx = relocs->next_symndx();
  750. if (personality_symndx == -1U)
  751. return false;
  752. if (personality_symndx < object->local_symbol_count())
  753. {
  754. // We can only merge this CIE if the personality routine is
  755. // a global symbol. We can still read the FDEs.
  756. mergeable = false;
  757. }
  758. else
  759. {
  760. const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
  761. if (personality_symndx >= symbols_size / sym_size)
  762. return false;
  763. elfcpp::Sym<size, big_endian> sym(symbols
  764. + (personality_symndx * sym_size));
  765. unsigned int name_offset = sym.get_st_name();
  766. if (name_offset >= symbol_names_size)
  767. return false;
  768. personality_name = (reinterpret_cast<const char*>(symbol_names)
  769. + name_offset);
  770. }
  771. int r = relocs->advance(per_offset + 1);
  772. gold_assert(r == 1);
  773. }
  774. if (relocs->advance(pcieend - pcontents) > 0)
  775. return false;
  776. Cie cie(object, shndx, (pcie - 8) - pcontents, fde_encoding,
  777. personality_name, pcie, pcieend - pcie);
  778. Cie* cie_pointer = NULL;
  779. if (mergeable)
  780. {
  781. Cie_offsets::iterator find_cie = this->cie_offsets_.find(&cie);
  782. if (find_cie != this->cie_offsets_.end())
  783. cie_pointer = *find_cie;
  784. else
  785. {
  786. // See if we already saw this CIE in this object file.
  787. for (New_cies::const_iterator pc = new_cies->begin();
  788. pc != new_cies->end();
  789. ++pc)
  790. {
  791. if (*(pc->first) == cie)
  792. {
  793. cie_pointer = pc->first;
  794. break;
  795. }
  796. }
  797. }
  798. }
  799. if (cie_pointer == NULL)
  800. {
  801. cie_pointer = new Cie(cie);
  802. new_cies->push_back(std::make_pair(cie_pointer, mergeable));
  803. }
  804. else
  805. {
  806. // We are deleting this CIE. Record that in our mapping from
  807. // input sections to the output section. At this point we don't
  808. // know for sure that we are doing a special mapping for this
  809. // input section, but that's OK--if we don't do a special
  810. // mapping, nobody will ever ask for the mapping we add here.
  811. object->add_merge_mapping(this, shndx, (pcie - 8) - pcontents,
  812. pcieend - (pcie - 8), -1);
  813. }
  814. // Record this CIE plus the offset in the input section.
  815. cies->insert(std::make_pair(pcie - pcontents, cie_pointer));
  816. return true;
  817. }
  818. // Read an FDE. Return false if we can't parse the information.
  819. template<int size, bool big_endian>
  820. bool
  821. Eh_frame::read_fde(Sized_relobj_file<size, big_endian>* object,
  822. unsigned int shndx,
  823. const unsigned char* symbols,
  824. section_size_type symbols_size,
  825. const unsigned char* pcontents,
  826. unsigned int offset,
  827. const unsigned char* pfde,
  828. const unsigned char* pfdeend,
  829. Track_relocs<size, big_endian>* relocs,
  830. Offsets_to_cie* cies)
  831. {
  832. // OFFSET is the distance between the 4 bytes before PFDE to the
  833. // start of the CIE. The offset we recorded for the CIE is 8 bytes
  834. // after the start of the CIE--after the length and the zero tag.
  835. unsigned int cie_offset = (pfde - 4 - pcontents) - offset + 8;
  836. Offsets_to_cie::const_iterator pcie = cies->find(cie_offset);
  837. if (pcie == cies->end())
  838. return false;
  839. Cie* cie = pcie->second;
  840. int pc_size = 0;
  841. switch (cie->fde_encoding() & 7)
  842. {
  843. case elfcpp::DW_EH_PE_udata2:
  844. pc_size = 2;
  845. break;
  846. case elfcpp::DW_EH_PE_udata4:
  847. pc_size = 4;
  848. break;
  849. case elfcpp::DW_EH_PE_udata8:
  850. gold_assert(size == 64);
  851. pc_size = 8;
  852. break;
  853. case elfcpp::DW_EH_PE_absptr:
  854. pc_size = size == 32 ? 4 : 8;
  855. break;
  856. default:
  857. // All other cases were rejected in Eh_frame::read_cie.
  858. gold_unreachable();
  859. }
  860. // The FDE should start with a reloc to the start of the code which
  861. // it describes.
  862. if (relocs->advance(pfde - pcontents) > 0)
  863. return false;
  864. if (relocs->next_offset() != pfde - pcontents)
  865. {
  866. // In an object produced by a relocatable link, gold may have
  867. // discarded a COMDAT group in the previous link, but not the
  868. // corresponding FDEs. In that case, gold will have discarded
  869. // the relocations, so the FDE will have a non-relocatable zero
  870. // (regardless of whether the PC encoding is absolute, pc-relative,
  871. // or data-relative) instead of a pointer to the start of the code.
  872. uint64_t pc_value = 0;
  873. switch (pc_size)
  874. {
  875. case 2:
  876. pc_value = elfcpp::Swap<16, big_endian>::readval(pfde);
  877. break;
  878. case 4:
  879. pc_value = elfcpp::Swap<32, big_endian>::readval(pfde);
  880. break;
  881. case 8:
  882. pc_value = elfcpp::Swap_unaligned<64, big_endian>::readval(pfde);
  883. break;
  884. default:
  885. gold_unreachable();
  886. }
  887. if (pc_value == 0)
  888. {
  889. // This FDE applies to a discarded function. We
  890. // can discard this FDE.
  891. object->add_merge_mapping(this, shndx, (pfde - 8) - pcontents,
  892. pfdeend - (pfde - 8), -1);
  893. return true;
  894. }
  895. // Otherwise, reject the FDE.
  896. return false;
  897. }
  898. unsigned int symndx = relocs->next_symndx();
  899. if (symndx == -1U)
  900. return false;
  901. // There can be another reloc in the FDE, if the CIE specifies an
  902. // LSDA (language specific data area). We currently don't care. We
  903. // will care later if we want to optimize the LSDA from an absolute
  904. // pointer to a PC relative offset when generating a shared library.
  905. relocs->advance(pfdeend - pcontents);
  906. // Find the section index for code that this FDE describes.
  907. // If we have discarded the section, we can also discard the FDE.
  908. unsigned int fde_shndx;
  909. const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
  910. if (symndx >= symbols_size / sym_size)
  911. return false;
  912. elfcpp::Sym<size, big_endian> sym(symbols + symndx * sym_size);
  913. bool is_ordinary;
  914. fde_shndx = object->adjust_sym_shndx(symndx, sym.get_st_shndx(),
  915. &is_ordinary);
  916. bool is_discarded = (is_ordinary
  917. && fde_shndx != elfcpp::SHN_UNDEF
  918. && fde_shndx < object->shnum()
  919. && !object->is_section_included(fde_shndx));
  920. // Fetch the address range field from the FDE. The offset and size
  921. // of the field depends on the PC encoding given in the CIE, but
  922. // it is always an absolute value. If the address range is 0, this
  923. // FDE corresponds to a function that was discarded during optimization
  924. // (too late to discard the corresponding FDE).
  925. uint64_t address_range = 0;
  926. switch (pc_size)
  927. {
  928. case 2:
  929. address_range = elfcpp::Swap<16, big_endian>::readval(pfde + 2);
  930. break;
  931. case 4:
  932. address_range = elfcpp::Swap<32, big_endian>::readval(pfde + 4);
  933. break;
  934. case 8:
  935. address_range = elfcpp::Swap_unaligned<64, big_endian>::readval(pfde + 8);
  936. break;
  937. default:
  938. gold_unreachable();
  939. }
  940. if (is_discarded || address_range == 0)
  941. {
  942. // This FDE applies to a discarded function. We
  943. // can discard this FDE.
  944. object->add_merge_mapping(this, shndx, (pfde - 8) - pcontents,
  945. pfdeend - (pfde - 8), -1);
  946. return true;
  947. }
  948. cie->add_fde(new Fde(object, shndx, (pfde - 8) - pcontents,
  949. pfde, pfdeend - pfde));
  950. return true;
  951. }
  952. // Add unwind information for a PLT.
  953. void
  954. Eh_frame::add_ehframe_for_plt(Output_data* plt, const unsigned char* cie_data,
  955. size_t cie_length, const unsigned char* fde_data,
  956. size_t fde_length)
  957. {
  958. Cie cie(NULL, 0, 0, elfcpp::DW_EH_PE_pcrel | elfcpp::DW_EH_PE_sdata4, "",
  959. cie_data, cie_length);
  960. Cie_offsets::iterator find_cie = this->cie_offsets_.find(&cie);
  961. Cie* pcie;
  962. if (find_cie != this->cie_offsets_.end())
  963. pcie = *find_cie;
  964. else
  965. {
  966. gold_assert(!this->mappings_are_done_);
  967. pcie = new Cie(cie);
  968. this->cie_offsets_.insert(pcie);
  969. }
  970. Fde* fde = new Fde(plt, fde_data, fde_length, this->mappings_are_done_);
  971. pcie->add_fde(fde);
  972. if (this->mappings_are_done_)
  973. this->final_data_size_ += align_address(fde_length + 8, this->addralign());
  974. }
  975. // Remove all post-map unwind information for a PLT.
  976. void
  977. Eh_frame::remove_ehframe_for_plt(Output_data* plt,
  978. const unsigned char* cie_data,
  979. size_t cie_length)
  980. {
  981. if (!this->mappings_are_done_)
  982. return;
  983. Cie cie(NULL, 0, 0, elfcpp::DW_EH_PE_pcrel | elfcpp::DW_EH_PE_sdata4, "",
  984. cie_data, cie_length);
  985. Cie_offsets::iterator find_cie = this->cie_offsets_.find(&cie);
  986. gold_assert (find_cie != this->cie_offsets_.end());
  987. Cie* pcie = *find_cie;
  988. while (pcie->fde_count() != 0)
  989. {
  990. const Fde* fde = pcie->last_fde();
  991. if (!fde->post_map(plt))
  992. break;
  993. size_t length = fde->length();
  994. this->final_data_size_ -= align_address(length + 8, this->addralign());
  995. pcie->remove_fde();
  996. }
  997. }
  998. // Return the number of FDEs.
  999. unsigned int
  1000. Eh_frame::fde_count() const
  1001. {
  1002. unsigned int ret = 0;
  1003. for (Unmergeable_cie_offsets::const_iterator p =
  1004. this->unmergeable_cie_offsets_.begin();
  1005. p != this->unmergeable_cie_offsets_.end();
  1006. ++p)
  1007. ret += (*p)->fde_count();
  1008. for (Cie_offsets::const_iterator p = this->cie_offsets_.begin();
  1009. p != this->cie_offsets_.end();
  1010. ++p)
  1011. ret += (*p)->fde_count();
  1012. return ret;
  1013. }
  1014. // Set the final data size.
  1015. void
  1016. Eh_frame::set_final_data_size()
  1017. {
  1018. // We can be called more than once if Layout::set_segment_offsets
  1019. // finds a better mapping. We don't want to add all the mappings
  1020. // again.
  1021. if (this->mappings_are_done_)
  1022. {
  1023. this->set_data_size(this->final_data_size_);
  1024. return;
  1025. }
  1026. section_offset_type output_start = 0;
  1027. if (this->is_offset_valid())
  1028. output_start = this->offset() - this->output_section()->offset();
  1029. section_offset_type output_offset = output_start;
  1030. for (Unmergeable_cie_offsets::iterator p =
  1031. this->unmergeable_cie_offsets_.begin();
  1032. p != this->unmergeable_cie_offsets_.end();
  1033. ++p)
  1034. output_offset = (*p)->set_output_offset(output_offset,
  1035. this->addralign(),
  1036. this);
  1037. for (Cie_offsets::iterator p = this->cie_offsets_.begin();
  1038. p != this->cie_offsets_.end();
  1039. ++p)
  1040. output_offset = (*p)->set_output_offset(output_offset,
  1041. this->addralign(),
  1042. this);
  1043. this->mappings_are_done_ = true;
  1044. this->final_data_size_ = output_offset - output_start;
  1045. gold_assert((output_offset & (this->addralign() - 1)) == 0);
  1046. this->set_data_size(this->final_data_size_);
  1047. }
  1048. // Return an output offset for an input offset.
  1049. bool
  1050. Eh_frame::do_output_offset(const Relobj* object, unsigned int shndx,
  1051. section_offset_type offset,
  1052. section_offset_type* poutput) const
  1053. {
  1054. return object->merge_output_offset(shndx, offset, poutput);
  1055. }
  1056. // Write the data to the output file.
  1057. void
  1058. Eh_frame::do_write(Output_file* of)
  1059. {
  1060. const off_t offset = this->offset();
  1061. const off_t oview_size = this->data_size();
  1062. unsigned char* const oview = of->get_output_view(offset, oview_size);
  1063. switch (parameters->size_and_endianness())
  1064. {
  1065. #ifdef HAVE_TARGET_32_LITTLE
  1066. case Parameters::TARGET_32_LITTLE:
  1067. this->do_sized_write<32, false>(oview);
  1068. break;
  1069. #endif
  1070. #ifdef HAVE_TARGET_32_BIG
  1071. case Parameters::TARGET_32_BIG:
  1072. this->do_sized_write<32, true>(oview);
  1073. break;
  1074. #endif
  1075. #ifdef HAVE_TARGET_64_LITTLE
  1076. case Parameters::TARGET_64_LITTLE:
  1077. this->do_sized_write<64, false>(oview);
  1078. break;
  1079. #endif
  1080. #ifdef HAVE_TARGET_64_BIG
  1081. case Parameters::TARGET_64_BIG:
  1082. this->do_sized_write<64, true>(oview);
  1083. break;
  1084. #endif
  1085. default:
  1086. gold_unreachable();
  1087. }
  1088. of->write_output_view(offset, oview_size, oview);
  1089. }
  1090. // Write the data to the output file--template version.
  1091. template<int size, bool big_endian>
  1092. void
  1093. Eh_frame::do_sized_write(unsigned char* oview)
  1094. {
  1095. uint64_t address = this->address();
  1096. unsigned int addralign = this->addralign();
  1097. section_offset_type o = 0;
  1098. const off_t output_offset = this->offset() - this->output_section()->offset();
  1099. Post_fdes post_fdes;
  1100. for (Unmergeable_cie_offsets::iterator p =
  1101. this->unmergeable_cie_offsets_.begin();
  1102. p != this->unmergeable_cie_offsets_.end();
  1103. ++p)
  1104. o = (*p)->write<size, big_endian>(oview, output_offset, o, address,
  1105. addralign, this->eh_frame_hdr_,
  1106. &post_fdes);
  1107. for (Cie_offsets::iterator p = this->cie_offsets_.begin();
  1108. p != this->cie_offsets_.end();
  1109. ++p)
  1110. o = (*p)->write<size, big_endian>(oview, output_offset, o, address,
  1111. addralign, this->eh_frame_hdr_,
  1112. &post_fdes);
  1113. for (Post_fdes::iterator p = post_fdes.begin();
  1114. p != post_fdes.end();
  1115. ++p)
  1116. o = (*p).fde->write<size, big_endian>(oview, output_offset, o, address,
  1117. addralign, (*p).cie_offset,
  1118. (*p).fde_encoding,
  1119. this->eh_frame_hdr_);
  1120. }
  1121. #ifdef HAVE_TARGET_32_LITTLE
  1122. template
  1123. Eh_frame::Eh_frame_section_disposition
  1124. Eh_frame::add_ehframe_input_section<32, false>(
  1125. Sized_relobj_file<32, false>* object,
  1126. const unsigned char* symbols,
  1127. section_size_type symbols_size,
  1128. const unsigned char* symbol_names,
  1129. section_size_type symbol_names_size,
  1130. unsigned int shndx,
  1131. unsigned int reloc_shndx,
  1132. unsigned int reloc_type);
  1133. #endif
  1134. #ifdef HAVE_TARGET_32_BIG
  1135. template
  1136. Eh_frame::Eh_frame_section_disposition
  1137. Eh_frame::add_ehframe_input_section<32, true>(
  1138. Sized_relobj_file<32, true>* object,
  1139. const unsigned char* symbols,
  1140. section_size_type symbols_size,
  1141. const unsigned char* symbol_names,
  1142. section_size_type symbol_names_size,
  1143. unsigned int shndx,
  1144. unsigned int reloc_shndx,
  1145. unsigned int reloc_type);
  1146. #endif
  1147. #ifdef HAVE_TARGET_64_LITTLE
  1148. template
  1149. Eh_frame::Eh_frame_section_disposition
  1150. Eh_frame::add_ehframe_input_section<64, false>(
  1151. Sized_relobj_file<64, false>* object,
  1152. const unsigned char* symbols,
  1153. section_size_type symbols_size,
  1154. const unsigned char* symbol_names,
  1155. section_size_type symbol_names_size,
  1156. unsigned int shndx,
  1157. unsigned int reloc_shndx,
  1158. unsigned int reloc_type);
  1159. #endif
  1160. #ifdef HAVE_TARGET_64_BIG
  1161. template
  1162. Eh_frame::Eh_frame_section_disposition
  1163. Eh_frame::add_ehframe_input_section<64, true>(
  1164. Sized_relobj_file<64, true>* object,
  1165. const unsigned char* symbols,
  1166. section_size_type symbols_size,
  1167. const unsigned char* symbol_names,
  1168. section_size_type symbol_names_size,
  1169. unsigned int shndx,
  1170. unsigned int reloc_shndx,
  1171. unsigned int reloc_type);
  1172. #endif
  1173. } // End namespace gold.