merge.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963
  1. /* SEC_MERGE support.
  2. Copyright (C) 2001-2022 Free Software Foundation, Inc.
  3. Written by Jakub Jelinek <jakub@redhat.com>.
  4. This file is part of BFD, the Binary File Descriptor library.
  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. /* This file contains support for merging duplicate entities within sections,
  18. as used in ELF SHF_MERGE. */
  19. #include "sysdep.h"
  20. #include <limits.h>
  21. #include "bfd.h"
  22. #include "elf-bfd.h"
  23. #include "libbfd.h"
  24. #include "hashtab.h"
  25. #include "libiberty.h"
  26. struct sec_merge_sec_info;
  27. /* An entry in the section merge hash table. */
  28. struct sec_merge_hash_entry
  29. {
  30. struct bfd_hash_entry root;
  31. /* Length of this entry. This includes the zero terminator. */
  32. unsigned int len;
  33. /* Start of this string needs to be aligned to
  34. alignment octets (not 1 << align). */
  35. unsigned int alignment;
  36. union
  37. {
  38. /* Index within the merged section. */
  39. bfd_size_type index;
  40. /* Entry this is a suffix of (if alignment is 0). */
  41. struct sec_merge_hash_entry *suffix;
  42. } u;
  43. /* Which section is it in. */
  44. struct sec_merge_sec_info *secinfo;
  45. /* Next entity in the hash table. */
  46. struct sec_merge_hash_entry *next;
  47. };
  48. /* The section merge hash table. */
  49. struct sec_merge_hash
  50. {
  51. struct bfd_hash_table table;
  52. /* Next available index. */
  53. bfd_size_type size;
  54. /* First entity in the SEC_MERGE sections of this type. */
  55. struct sec_merge_hash_entry *first;
  56. /* Last entity in the SEC_MERGE sections of this type. */
  57. struct sec_merge_hash_entry *last;
  58. /* Entity size. */
  59. unsigned int entsize;
  60. /* Are entries fixed size or zero terminated strings? */
  61. bool strings;
  62. };
  63. struct sec_merge_info
  64. {
  65. /* Chain of sec_merge_infos. */
  66. struct sec_merge_info *next;
  67. /* Chain of sec_merge_sec_infos. */
  68. struct sec_merge_sec_info *chain;
  69. /* A hash table used to hold section content. */
  70. struct sec_merge_hash *htab;
  71. };
  72. struct sec_merge_sec_info
  73. {
  74. /* Chain of sec_merge_sec_infos. */
  75. struct sec_merge_sec_info *next;
  76. /* The corresponding section. */
  77. asection *sec;
  78. /* Pointer to merge_info pointing to us. */
  79. void **psecinfo;
  80. /* A hash table used to hold section content. */
  81. struct sec_merge_hash *htab;
  82. /* First string in this section. */
  83. struct sec_merge_hash_entry *first_str;
  84. /* Original section content. */
  85. unsigned char contents[1];
  86. };
  87. /* Routine to create an entry in a section merge hashtab. */
  88. static struct bfd_hash_entry *
  89. sec_merge_hash_newfunc (struct bfd_hash_entry *entry,
  90. struct bfd_hash_table *table, const char *string)
  91. {
  92. /* Allocate the structure if it has not already been allocated by a
  93. subclass. */
  94. if (entry == NULL)
  95. entry = (struct bfd_hash_entry *)
  96. bfd_hash_allocate (table, sizeof (struct sec_merge_hash_entry));
  97. if (entry == NULL)
  98. return NULL;
  99. /* Call the allocation method of the superclass. */
  100. entry = bfd_hash_newfunc (entry, table, string);
  101. if (entry != NULL)
  102. {
  103. /* Initialize the local fields. */
  104. struct sec_merge_hash_entry *ret = (struct sec_merge_hash_entry *) entry;
  105. ret->u.suffix = NULL;
  106. ret->alignment = 0;
  107. ret->secinfo = NULL;
  108. ret->next = NULL;
  109. }
  110. return entry;
  111. }
  112. /* Look up an entry in a section merge hash table. */
  113. static struct sec_merge_hash_entry *
  114. sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string,
  115. unsigned int alignment, bool create)
  116. {
  117. const unsigned char *s;
  118. unsigned long hash;
  119. unsigned int c;
  120. struct sec_merge_hash_entry *hashp;
  121. unsigned int len, i;
  122. unsigned int _index;
  123. hash = 0;
  124. len = 0;
  125. s = (const unsigned char *) string;
  126. if (table->strings)
  127. {
  128. if (table->entsize == 1)
  129. {
  130. while ((c = *s++) != '\0')
  131. {
  132. hash += c + (c << 17);
  133. hash ^= hash >> 2;
  134. ++len;
  135. }
  136. hash += len + (len << 17);
  137. }
  138. else
  139. {
  140. for (;;)
  141. {
  142. for (i = 0; i < table->entsize; ++i)
  143. if (s[i] != '\0')
  144. break;
  145. if (i == table->entsize)
  146. break;
  147. for (i = 0; i < table->entsize; ++i)
  148. {
  149. c = *s++;
  150. hash += c + (c << 17);
  151. hash ^= hash >> 2;
  152. }
  153. ++len;
  154. }
  155. hash += len + (len << 17);
  156. len *= table->entsize;
  157. }
  158. hash ^= hash >> 2;
  159. len += table->entsize;
  160. }
  161. else
  162. {
  163. for (i = 0; i < table->entsize; ++i)
  164. {
  165. c = *s++;
  166. hash += c + (c << 17);
  167. hash ^= hash >> 2;
  168. }
  169. len = table->entsize;
  170. }
  171. _index = hash % table->table.size;
  172. for (hashp = (struct sec_merge_hash_entry *) table->table.table[_index];
  173. hashp != NULL;
  174. hashp = (struct sec_merge_hash_entry *) hashp->root.next)
  175. {
  176. if (hashp->root.hash == hash
  177. && len == hashp->len
  178. && memcmp (hashp->root.string, string, len) == 0)
  179. {
  180. /* If the string we found does not have at least the required
  181. alignment, we need to insert another copy. */
  182. if (hashp->alignment < alignment)
  183. {
  184. if (create)
  185. {
  186. /* Mark the less aligned copy as deleted. */
  187. hashp->len = 0;
  188. hashp->alignment = 0;
  189. }
  190. break;
  191. }
  192. return hashp;
  193. }
  194. }
  195. if (! create)
  196. return NULL;
  197. hashp = ((struct sec_merge_hash_entry *)
  198. bfd_hash_insert (&table->table, string, hash));
  199. if (hashp == NULL)
  200. return NULL;
  201. hashp->len = len;
  202. hashp->alignment = alignment;
  203. return hashp;
  204. }
  205. /* Create a new hash table. */
  206. static struct sec_merge_hash *
  207. sec_merge_init (unsigned int entsize, bool strings)
  208. {
  209. struct sec_merge_hash *table;
  210. table = (struct sec_merge_hash *) bfd_malloc (sizeof (struct sec_merge_hash));
  211. if (table == NULL)
  212. return NULL;
  213. if (! bfd_hash_table_init_n (&table->table, sec_merge_hash_newfunc,
  214. sizeof (struct sec_merge_hash_entry), 16699))
  215. {
  216. free (table);
  217. return NULL;
  218. }
  219. table->size = 0;
  220. table->first = NULL;
  221. table->last = NULL;
  222. table->entsize = entsize;
  223. table->strings = strings;
  224. return table;
  225. }
  226. /* Get the index of an entity in a hash table, adding it if it is not
  227. already present. */
  228. static struct sec_merge_hash_entry *
  229. sec_merge_add (struct sec_merge_hash *tab, const char *str,
  230. unsigned int alignment, struct sec_merge_sec_info *secinfo)
  231. {
  232. struct sec_merge_hash_entry *entry;
  233. entry = sec_merge_hash_lookup (tab, str, alignment, true);
  234. if (entry == NULL)
  235. return NULL;
  236. if (entry->secinfo == NULL)
  237. {
  238. tab->size++;
  239. entry->secinfo = secinfo;
  240. if (tab->first == NULL)
  241. tab->first = entry;
  242. else
  243. tab->last->next = entry;
  244. tab->last = entry;
  245. }
  246. return entry;
  247. }
  248. static bool
  249. sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry,
  250. unsigned char *contents, file_ptr offset)
  251. {
  252. struct sec_merge_sec_info *secinfo = entry->secinfo;
  253. asection *sec = secinfo->sec;
  254. char *pad = NULL;
  255. bfd_size_type off = 0;
  256. unsigned int opb = bfd_octets_per_byte (abfd, sec);
  257. int alignment_power = sec->output_section->alignment_power * opb;
  258. bfd_size_type pad_len; /* Octets. */
  259. /* FIXME: If alignment_power is 0 then really we should scan the
  260. entry list for the largest required alignment and use that. */
  261. pad_len = alignment_power ? ((bfd_size_type) 1 << alignment_power) : 16;
  262. pad = (char *) bfd_zmalloc (pad_len);
  263. if (pad == NULL)
  264. return false;
  265. for (; entry != NULL && entry->secinfo == secinfo; entry = entry->next)
  266. {
  267. const char *str;
  268. bfd_size_type len;
  269. len = -off & (entry->alignment - 1);
  270. if (len != 0)
  271. {
  272. BFD_ASSERT (len <= pad_len);
  273. if (contents)
  274. {
  275. memcpy (contents + offset, pad, len);
  276. offset += len;
  277. }
  278. else if (bfd_bwrite (pad, len, abfd) != len)
  279. goto err;
  280. off += len;
  281. }
  282. str = entry->root.string;
  283. len = entry->len;
  284. if (contents)
  285. {
  286. memcpy (contents + offset, str, len);
  287. offset += len;
  288. }
  289. else if (bfd_bwrite (str, len, abfd) != len)
  290. goto err;
  291. off += len;
  292. }
  293. /* Trailing alignment needed? */
  294. off = sec->size - off;
  295. if (off != 0)
  296. {
  297. BFD_ASSERT (off <= pad_len);
  298. if (contents)
  299. memcpy (contents + offset, pad, off);
  300. else if (bfd_bwrite (pad, off, abfd) != off)
  301. goto err;
  302. }
  303. free (pad);
  304. return true;
  305. err:
  306. free (pad);
  307. return false;
  308. }
  309. /* Register a SEC_MERGE section as a candidate for merging.
  310. This function is called for all non-dynamic SEC_MERGE input sections. */
  311. bool
  312. _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec,
  313. void **psecinfo)
  314. {
  315. struct sec_merge_info *sinfo;
  316. struct sec_merge_sec_info *secinfo;
  317. unsigned int alignment_power; /* Octets. */
  318. unsigned int align; /* Octets. */
  319. bfd_size_type amt;
  320. bfd_byte *contents;
  321. unsigned int opb = bfd_octets_per_byte (abfd, sec);
  322. if ((abfd->flags & DYNAMIC) != 0
  323. || (sec->flags & SEC_MERGE) == 0)
  324. abort ();
  325. if (sec->size == 0
  326. || (sec->flags & SEC_EXCLUDE) != 0
  327. || sec->entsize == 0)
  328. return true;
  329. if (sec->size % sec->entsize != 0)
  330. return true;
  331. if ((sec->flags & SEC_RELOC) != 0)
  332. {
  333. /* We aren't prepared to handle relocations in merged sections. */
  334. return true;
  335. }
  336. #ifndef CHAR_BIT
  337. #define CHAR_BIT 8
  338. #endif
  339. alignment_power = sec->alignment_power * opb;
  340. if (alignment_power >= sizeof (align) * CHAR_BIT)
  341. return true;
  342. align = 1u << alignment_power;
  343. if ((sec->entsize < align
  344. && ((sec->entsize & (sec->entsize - 1))
  345. || !(sec->flags & SEC_STRINGS)))
  346. || (sec->entsize > align
  347. && (sec->entsize & (align - 1))))
  348. {
  349. /* Sanity check. If string character size is smaller than
  350. alignment, then we require character size to be a power
  351. of 2, otherwise character size must be integer multiple
  352. of alignment. For non-string constants, alignment must
  353. be smaller than or equal to entity size and entity size
  354. must be integer multiple of alignment. */
  355. return true;
  356. }
  357. for (sinfo = (struct sec_merge_info *) *psinfo; sinfo; sinfo = sinfo->next)
  358. if ((secinfo = sinfo->chain)
  359. && ! ((secinfo->sec->flags ^ sec->flags) & (SEC_MERGE | SEC_STRINGS))
  360. && secinfo->sec->entsize == sec->entsize
  361. && secinfo->sec->alignment_power == sec->alignment_power
  362. && secinfo->sec->output_section == sec->output_section)
  363. break;
  364. if (sinfo == NULL)
  365. {
  366. /* Initialize the information we need to keep track of. */
  367. sinfo = (struct sec_merge_info *)
  368. bfd_alloc (abfd, sizeof (struct sec_merge_info));
  369. if (sinfo == NULL)
  370. goto error_return;
  371. sinfo->next = (struct sec_merge_info *) *psinfo;
  372. sinfo->chain = NULL;
  373. *psinfo = sinfo;
  374. sinfo->htab = sec_merge_init (sec->entsize, (sec->flags & SEC_STRINGS));
  375. if (sinfo->htab == NULL)
  376. goto error_return;
  377. }
  378. /* Read the section from abfd. */
  379. amt = sizeof (struct sec_merge_sec_info) - 1 + sec->size;
  380. if (sec->flags & SEC_STRINGS)
  381. /* Some versions of gcc may emit a string without a zero terminator.
  382. See http://gcc.gnu.org/ml/gcc-patches/2006-06/msg01004.html
  383. Allocate space for an extra zero. */
  384. amt += sec->entsize;
  385. *psecinfo = bfd_alloc (abfd, amt);
  386. if (*psecinfo == NULL)
  387. goto error_return;
  388. secinfo = (struct sec_merge_sec_info *) *psecinfo;
  389. if (sinfo->chain)
  390. {
  391. secinfo->next = sinfo->chain->next;
  392. sinfo->chain->next = secinfo;
  393. }
  394. else
  395. secinfo->next = secinfo;
  396. sinfo->chain = secinfo;
  397. secinfo->sec = sec;
  398. secinfo->psecinfo = psecinfo;
  399. secinfo->htab = sinfo->htab;
  400. secinfo->first_str = NULL;
  401. sec->rawsize = sec->size;
  402. if (sec->flags & SEC_STRINGS)
  403. memset (secinfo->contents + sec->size, 0, sec->entsize);
  404. contents = secinfo->contents;
  405. if (! bfd_get_full_section_contents (sec->owner, sec, &contents))
  406. goto error_return;
  407. return true;
  408. error_return:
  409. *psecinfo = NULL;
  410. return false;
  411. }
  412. /* Record one section into the hash table. */
  413. static bool
  414. record_section (struct sec_merge_info *sinfo,
  415. struct sec_merge_sec_info *secinfo)
  416. {
  417. asection *sec = secinfo->sec;
  418. struct sec_merge_hash_entry *entry;
  419. bool nul;
  420. unsigned char *p, *end;
  421. bfd_vma mask, eltalign;
  422. unsigned int align, i;
  423. align = sec->alignment_power;
  424. end = secinfo->contents + sec->size;
  425. nul = false;
  426. mask = ((bfd_vma) 1 << align) - 1;
  427. if (sec->flags & SEC_STRINGS)
  428. {
  429. for (p = secinfo->contents; p < end; )
  430. {
  431. eltalign = p - secinfo->contents;
  432. eltalign = ((eltalign ^ (eltalign - 1)) + 1) >> 1;
  433. if (!eltalign || eltalign > mask)
  434. eltalign = mask + 1;
  435. entry = sec_merge_add (sinfo->htab, (char *) p, (unsigned) eltalign,
  436. secinfo);
  437. if (! entry)
  438. goto error_return;
  439. p += entry->len;
  440. if (sec->entsize == 1)
  441. {
  442. while (p < end && *p == 0)
  443. {
  444. if (!nul && !((p - secinfo->contents) & mask))
  445. {
  446. nul = true;
  447. entry = sec_merge_add (sinfo->htab, "",
  448. (unsigned) mask + 1, secinfo);
  449. if (! entry)
  450. goto error_return;
  451. }
  452. p++;
  453. }
  454. }
  455. else
  456. {
  457. while (p < end)
  458. {
  459. for (i = 0; i < sec->entsize; i++)
  460. if (p[i] != '\0')
  461. break;
  462. if (i != sec->entsize)
  463. break;
  464. if (!nul && !((p - secinfo->contents) & mask))
  465. {
  466. nul = true;
  467. entry = sec_merge_add (sinfo->htab, (char *) p,
  468. (unsigned) mask + 1, secinfo);
  469. if (! entry)
  470. goto error_return;
  471. }
  472. p += sec->entsize;
  473. }
  474. }
  475. }
  476. }
  477. else
  478. {
  479. for (p = secinfo->contents; p < end; p += sec->entsize)
  480. {
  481. entry = sec_merge_add (sinfo->htab, (char *) p, 1, secinfo);
  482. if (! entry)
  483. goto error_return;
  484. }
  485. }
  486. return true;
  487. error_return:
  488. for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
  489. *secinfo->psecinfo = NULL;
  490. return false;
  491. }
  492. /* qsort comparison function. Won't ever return zero as all entries
  493. differ, so there is no issue with qsort stability here. */
  494. static int
  495. strrevcmp (const void *a, const void *b)
  496. {
  497. struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
  498. struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
  499. unsigned int lenA = A->len;
  500. unsigned int lenB = B->len;
  501. const unsigned char *s = (const unsigned char *) A->root.string + lenA - 1;
  502. const unsigned char *t = (const unsigned char *) B->root.string + lenB - 1;
  503. int l = lenA < lenB ? lenA : lenB;
  504. while (l)
  505. {
  506. if (*s != *t)
  507. return (int) *s - (int) *t;
  508. s--;
  509. t--;
  510. l--;
  511. }
  512. return lenA - lenB;
  513. }
  514. /* Like strrevcmp, but for the case where all strings have the same
  515. alignment > entsize. */
  516. static int
  517. strrevcmp_align (const void *a, const void *b)
  518. {
  519. struct sec_merge_hash_entry *A = *(struct sec_merge_hash_entry **) a;
  520. struct sec_merge_hash_entry *B = *(struct sec_merge_hash_entry **) b;
  521. unsigned int lenA = A->len;
  522. unsigned int lenB = B->len;
  523. const unsigned char *s = (const unsigned char *) A->root.string + lenA - 1;
  524. const unsigned char *t = (const unsigned char *) B->root.string + lenB - 1;
  525. int l = lenA < lenB ? lenA : lenB;
  526. int tail_align = (lenA & (A->alignment - 1)) - (lenB & (A->alignment - 1));
  527. if (tail_align != 0)
  528. return tail_align;
  529. while (l)
  530. {
  531. if (*s != *t)
  532. return (int) *s - (int) *t;
  533. s--;
  534. t--;
  535. l--;
  536. }
  537. return lenA - lenB;
  538. }
  539. static inline int
  540. is_suffix (const struct sec_merge_hash_entry *A,
  541. const struct sec_merge_hash_entry *B)
  542. {
  543. if (A->len <= B->len)
  544. /* B cannot be a suffix of A unless A is equal to B, which is guaranteed
  545. not to be equal by the hash table. */
  546. return 0;
  547. return memcmp (A->root.string + (A->len - B->len),
  548. B->root.string, B->len) == 0;
  549. }
  550. /* This is a helper function for _bfd_merge_sections. It attempts to
  551. merge strings matching suffixes of longer strings. */
  552. static struct sec_merge_sec_info *
  553. merge_strings (struct sec_merge_info *sinfo)
  554. {
  555. struct sec_merge_hash_entry **array, **a, *e;
  556. struct sec_merge_sec_info *secinfo;
  557. bfd_size_type size, amt;
  558. unsigned int alignment = 0;
  559. /* Now sort the strings */
  560. amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *);
  561. array = (struct sec_merge_hash_entry **) bfd_malloc (amt);
  562. if (array == NULL)
  563. return NULL;
  564. for (e = sinfo->htab->first, a = array; e; e = e->next)
  565. if (e->alignment)
  566. {
  567. *a++ = e;
  568. /* Adjust the length to not include the zero terminator. */
  569. e->len -= sinfo->htab->entsize;
  570. if (alignment != e->alignment)
  571. {
  572. if (alignment == 0)
  573. alignment = e->alignment;
  574. else
  575. alignment = (unsigned) -1;
  576. }
  577. }
  578. sinfo->htab->size = a - array;
  579. if (sinfo->htab->size != 0)
  580. {
  581. qsort (array, (size_t) sinfo->htab->size,
  582. sizeof (struct sec_merge_hash_entry *),
  583. (alignment != (unsigned) -1 && alignment > sinfo->htab->entsize
  584. ? strrevcmp_align : strrevcmp));
  585. /* Loop over the sorted array and merge suffixes */
  586. e = *--a;
  587. e->len += sinfo->htab->entsize;
  588. while (--a >= array)
  589. {
  590. struct sec_merge_hash_entry *cmp = *a;
  591. cmp->len += sinfo->htab->entsize;
  592. if (e->alignment >= cmp->alignment
  593. && !((e->len - cmp->len) & (cmp->alignment - 1))
  594. && is_suffix (e, cmp))
  595. {
  596. cmp->u.suffix = e;
  597. cmp->alignment = 0;
  598. }
  599. else
  600. e = cmp;
  601. }
  602. }
  603. free (array);
  604. /* Now assign positions to the strings we want to keep. */
  605. size = 0;
  606. secinfo = sinfo->htab->first->secinfo;
  607. for (e = sinfo->htab->first; e; e = e->next)
  608. {
  609. if (e->secinfo != secinfo)
  610. {
  611. secinfo->sec->size = size;
  612. secinfo = e->secinfo;
  613. }
  614. if (e->alignment)
  615. {
  616. if (e->secinfo->first_str == NULL)
  617. {
  618. e->secinfo->first_str = e;
  619. size = 0;
  620. }
  621. size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1);
  622. e->u.index = size;
  623. size += e->len;
  624. }
  625. }
  626. secinfo->sec->size = size;
  627. /* And now adjust the rest, removing them from the chain (but not hashtable)
  628. at the same time. */
  629. for (a = &sinfo->htab->first, e = *a; e; e = e->next)
  630. if (e->alignment)
  631. a = &e->next;
  632. else
  633. {
  634. *a = e->next;
  635. if (e->len)
  636. {
  637. e->secinfo = e->u.suffix->secinfo;
  638. e->alignment = e->u.suffix->alignment;
  639. e->u.index = e->u.suffix->u.index + (e->u.suffix->len - e->len);
  640. }
  641. }
  642. return secinfo;
  643. }
  644. /* This function is called once after all SEC_MERGE sections are registered
  645. with _bfd_merge_section. */
  646. bool
  647. _bfd_merge_sections (bfd *abfd,
  648. struct bfd_link_info *info ATTRIBUTE_UNUSED,
  649. void *xsinfo,
  650. void (*remove_hook) (bfd *, asection *))
  651. {
  652. struct sec_merge_info *sinfo;
  653. for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
  654. {
  655. struct sec_merge_sec_info *secinfo;
  656. bfd_size_type align; /* Bytes. */
  657. if (! sinfo->chain)
  658. continue;
  659. /* Move sinfo->chain to head of the chain, terminate it. */
  660. secinfo = sinfo->chain;
  661. sinfo->chain = secinfo->next;
  662. secinfo->next = NULL;
  663. /* Record the sections into the hash table. */
  664. align = 1;
  665. for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
  666. if (secinfo->sec->flags & SEC_EXCLUDE)
  667. {
  668. *secinfo->psecinfo = NULL;
  669. if (remove_hook)
  670. (*remove_hook) (abfd, secinfo->sec);
  671. }
  672. else
  673. {
  674. if (!record_section (sinfo, secinfo))
  675. return false;
  676. if (align)
  677. {
  678. unsigned int opb = bfd_octets_per_byte (abfd, secinfo->sec);
  679. align = (bfd_size_type) 1 << secinfo->sec->alignment_power;
  680. if (((secinfo->sec->size / opb) & (align - 1)) != 0)
  681. align = 0;
  682. }
  683. }
  684. if (sinfo->htab->first == NULL)
  685. continue;
  686. if (sinfo->htab->strings)
  687. {
  688. secinfo = merge_strings (sinfo);
  689. if (!secinfo)
  690. return false;
  691. }
  692. else
  693. {
  694. struct sec_merge_hash_entry *e;
  695. bfd_size_type size = 0; /* Octets. */
  696. /* Things are much simpler for non-strings.
  697. Just assign them slots in the section. */
  698. secinfo = NULL;
  699. for (e = sinfo->htab->first; e; e = e->next)
  700. {
  701. if (e->secinfo->first_str == NULL)
  702. {
  703. if (secinfo)
  704. secinfo->sec->size = size;
  705. e->secinfo->first_str = e;
  706. size = 0;
  707. }
  708. size = (size + e->alignment - 1) & ~((bfd_vma) e->alignment - 1);
  709. e->u.index = size;
  710. size += e->len;
  711. secinfo = e->secinfo;
  712. }
  713. secinfo->sec->size = size;
  714. }
  715. /* If the input sections were padded according to their alignments,
  716. then pad the output too. */
  717. if (align)
  718. secinfo->sec->size = (secinfo->sec->size + align - 1) & -align;
  719. /* Finally remove all input sections which have not made it into
  720. the hash table at all. */
  721. for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
  722. if (secinfo->first_str == NULL)
  723. secinfo->sec->flags |= SEC_EXCLUDE | SEC_KEEP;
  724. }
  725. return true;
  726. }
  727. /* Write out the merged section. */
  728. bool
  729. _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
  730. {
  731. struct sec_merge_sec_info *secinfo;
  732. file_ptr pos;
  733. unsigned char *contents;
  734. Elf_Internal_Shdr *hdr;
  735. secinfo = (struct sec_merge_sec_info *) psecinfo;
  736. if (!secinfo)
  737. return false;
  738. if (secinfo->first_str == NULL)
  739. return true;
  740. /* FIXME: octets_per_byte. */
  741. hdr = &elf_section_data (sec->output_section)->this_hdr;
  742. if (hdr->sh_offset == (file_ptr) -1)
  743. {
  744. /* We must compress this section. Write output to the
  745. buffer. */
  746. contents = hdr->contents;
  747. if ((sec->output_section->flags & SEC_ELF_COMPRESS) == 0
  748. || contents == NULL)
  749. abort ();
  750. }
  751. else
  752. {
  753. contents = NULL;
  754. pos = sec->output_section->filepos + sec->output_offset;
  755. if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
  756. return false;
  757. }
  758. if (! sec_merge_emit (output_bfd, secinfo->first_str, contents,
  759. sec->output_offset))
  760. return false;
  761. return true;
  762. }
  763. /* Adjust an address in the SEC_MERGE section. Given OFFSET within
  764. *PSEC, this returns the new offset in the adjusted SEC_MERGE
  765. section and writes the new section back into *PSEC. */
  766. bfd_vma
  767. _bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec,
  768. void *psecinfo, bfd_vma offset)
  769. {
  770. struct sec_merge_sec_info *secinfo;
  771. struct sec_merge_hash_entry *entry;
  772. unsigned char *p;
  773. asection *sec = *psec;
  774. secinfo = (struct sec_merge_sec_info *) psecinfo;
  775. if (!secinfo)
  776. return offset;
  777. if (offset >= sec->rawsize)
  778. {
  779. if (offset > sec->rawsize)
  780. _bfd_error_handler
  781. /* xgettext:c-format */
  782. (_("%pB: access beyond end of merged section (%" PRId64 ")"),
  783. sec->owner, (int64_t) offset);
  784. return secinfo->first_str ? sec->size : 0;
  785. }
  786. if (secinfo->htab->strings)
  787. {
  788. if (sec->entsize == 1)
  789. {
  790. p = secinfo->contents + offset - 1;
  791. while (p >= secinfo->contents && *p)
  792. --p;
  793. ++p;
  794. }
  795. else
  796. {
  797. p = secinfo->contents + (offset / sec->entsize) * sec->entsize;
  798. p -= sec->entsize;
  799. while (p >= secinfo->contents)
  800. {
  801. unsigned int i;
  802. for (i = 0; i < sec->entsize; ++i)
  803. if (p[i] != '\0')
  804. break;
  805. if (i == sec->entsize)
  806. break;
  807. p -= sec->entsize;
  808. }
  809. p += sec->entsize;
  810. }
  811. }
  812. else
  813. {
  814. p = secinfo->contents + (offset / sec->entsize) * sec->entsize;
  815. }
  816. entry = sec_merge_hash_lookup (secinfo->htab, (char *) p, 0, false);
  817. if (!entry)
  818. {
  819. if (! secinfo->htab->strings)
  820. abort ();
  821. /* This should only happen if somebody points into the padding
  822. after a NUL character but before next entity. */
  823. if (*p)
  824. abort ();
  825. if (! secinfo->htab->first)
  826. abort ();
  827. entry = secinfo->htab->first;
  828. p = (secinfo->contents + (offset / sec->entsize + 1) * sec->entsize
  829. - entry->len);
  830. }
  831. *psec = entry->secinfo->sec;
  832. return entry->u.index + (secinfo->contents + offset - p);
  833. }
  834. /* Tidy up when done. */
  835. void
  836. _bfd_merge_sections_free (void *xsinfo)
  837. {
  838. struct sec_merge_info *sinfo;
  839. for (sinfo = (struct sec_merge_info *) xsinfo; sinfo; sinfo = sinfo->next)
  840. {
  841. bfd_hash_table_free (&sinfo->htab->table);
  842. free (sinfo->htab);
  843. }
  844. }