elf-properties.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. /* ELF program property support.
  2. Copyright (C) 2017-2022 Free Software Foundation, Inc.
  3. This file is part of BFD, the Binary File Descriptor library.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  15. MA 02110-1301, USA. */
  16. /* GNU program property draft is at:
  17. https://github.com/hjl-tools/linux-abi/wiki/property-draft.pdf
  18. */
  19. #include "sysdep.h"
  20. #include "bfd.h"
  21. #include "libbfd.h"
  22. #include "elf-bfd.h"
  23. /* Get a property, allocate a new one if needed. */
  24. elf_property *
  25. _bfd_elf_get_property (bfd *abfd, unsigned int type, unsigned int datasz)
  26. {
  27. elf_property_list *p, **lastp;
  28. if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
  29. {
  30. /* Never should happen. */
  31. abort ();
  32. }
  33. /* Keep the property list in order of type. */
  34. lastp = &elf_properties (abfd);
  35. for (p = *lastp; p; p = p->next)
  36. {
  37. /* Reuse the existing entry. */
  38. if (type == p->property.pr_type)
  39. {
  40. if (datasz > p->property.pr_datasz)
  41. {
  42. /* This can happen when mixing 32-bit and 64-bit objects. */
  43. p->property.pr_datasz = datasz;
  44. }
  45. return &p->property;
  46. }
  47. else if (type < p->property.pr_type)
  48. break;
  49. lastp = &p->next;
  50. }
  51. p = (elf_property_list *) bfd_alloc (abfd, sizeof (*p));
  52. if (p == NULL)
  53. {
  54. _bfd_error_handler (_("%pB: out of memory in _bfd_elf_get_property"),
  55. abfd);
  56. _exit (EXIT_FAILURE);
  57. }
  58. memset (p, 0, sizeof (*p));
  59. p->property.pr_type = type;
  60. p->property.pr_datasz = datasz;
  61. p->next = *lastp;
  62. *lastp = p;
  63. return &p->property;
  64. }
  65. /* Parse GNU properties. */
  66. bool
  67. _bfd_elf_parse_gnu_properties (bfd *abfd, Elf_Internal_Note *note)
  68. {
  69. const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  70. unsigned int align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4;
  71. bfd_byte *ptr = (bfd_byte *) note->descdata;
  72. bfd_byte *ptr_end = ptr + note->descsz;
  73. if (note->descsz < 8 || (note->descsz % align_size) != 0)
  74. {
  75. bad_size:
  76. _bfd_error_handler
  77. (_("warning: %pB: corrupt GNU_PROPERTY_TYPE (%ld) size: %#lx"),
  78. abfd, note->type, note->descsz);
  79. return false;
  80. }
  81. while (ptr != ptr_end)
  82. {
  83. unsigned int type;
  84. unsigned int datasz;
  85. elf_property *prop;
  86. if ((size_t) (ptr_end - ptr) < 8)
  87. goto bad_size;
  88. type = bfd_h_get_32 (abfd, ptr);
  89. datasz = bfd_h_get_32 (abfd, ptr + 4);
  90. ptr += 8;
  91. if (datasz > (size_t) (ptr_end - ptr))
  92. {
  93. _bfd_error_handler
  94. (_("warning: %pB: corrupt GNU_PROPERTY_TYPE (%ld) type (0x%x) datasz: 0x%x"),
  95. abfd, note->type, type, datasz);
  96. /* Clear all properties. */
  97. elf_properties (abfd) = NULL;
  98. return false;
  99. }
  100. if (type >= GNU_PROPERTY_LOPROC)
  101. {
  102. if (bed->elf_machine_code == EM_NONE)
  103. {
  104. /* Ignore processor-specific properties with generic ELF
  105. target vector. They should be handled by the matching
  106. ELF target vector. */
  107. goto next;
  108. }
  109. else if (type < GNU_PROPERTY_LOUSER
  110. && bed->parse_gnu_properties)
  111. {
  112. enum elf_property_kind kind
  113. = bed->parse_gnu_properties (abfd, type, ptr, datasz);
  114. if (kind == property_corrupt)
  115. {
  116. /* Clear all properties. */
  117. elf_properties (abfd) = NULL;
  118. return false;
  119. }
  120. else if (kind != property_ignored)
  121. goto next;
  122. }
  123. }
  124. else
  125. {
  126. switch (type)
  127. {
  128. case GNU_PROPERTY_STACK_SIZE:
  129. if (datasz != align_size)
  130. {
  131. _bfd_error_handler
  132. (_("warning: %pB: corrupt stack size: 0x%x"),
  133. abfd, datasz);
  134. /* Clear all properties. */
  135. elf_properties (abfd) = NULL;
  136. return false;
  137. }
  138. prop = _bfd_elf_get_property (abfd, type, datasz);
  139. if (datasz == 8)
  140. prop->u.number = bfd_h_get_64 (abfd, ptr);
  141. else
  142. prop->u.number = bfd_h_get_32 (abfd, ptr);
  143. prop->pr_kind = property_number;
  144. goto next;
  145. case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
  146. if (datasz != 0)
  147. {
  148. _bfd_error_handler
  149. (_("warning: %pB: corrupt no copy on protected size: 0x%x"),
  150. abfd, datasz);
  151. /* Clear all properties. */
  152. elf_properties (abfd) = NULL;
  153. return false;
  154. }
  155. prop = _bfd_elf_get_property (abfd, type, datasz);
  156. elf_has_no_copy_on_protected (abfd) = true;
  157. prop->pr_kind = property_number;
  158. goto next;
  159. default:
  160. if ((type >= GNU_PROPERTY_UINT32_AND_LO
  161. && type <= GNU_PROPERTY_UINT32_AND_HI)
  162. || (type >= GNU_PROPERTY_UINT32_OR_LO
  163. && type <= GNU_PROPERTY_UINT32_OR_HI))
  164. {
  165. if (datasz != 4)
  166. {
  167. _bfd_error_handler
  168. (_("error: %pB: <corrupt property (0x%x) size: 0x%x>"),
  169. abfd, type, datasz);
  170. /* Clear all properties. */
  171. elf_properties (abfd) = NULL;
  172. return false;
  173. }
  174. prop = _bfd_elf_get_property (abfd, type, datasz);
  175. prop->u.number |= bfd_h_get_32 (abfd, ptr);
  176. prop->pr_kind = property_number;
  177. if (type == GNU_PROPERTY_1_NEEDED
  178. && ((prop->u.number
  179. & GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS)
  180. != 0))
  181. {
  182. elf_has_indirect_extern_access (abfd) = true;
  183. /* GNU_PROPERTY_NO_COPY_ON_PROTECTED is implied. */
  184. elf_has_no_copy_on_protected (abfd) = true;
  185. }
  186. goto next;
  187. }
  188. break;
  189. }
  190. }
  191. _bfd_error_handler
  192. (_("warning: %pB: unsupported GNU_PROPERTY_TYPE (%ld) type: 0x%x"),
  193. abfd, note->type, type);
  194. next:
  195. ptr += (datasz + (align_size - 1)) & ~ (align_size - 1);
  196. }
  197. return true;
  198. }
  199. /* Merge GNU property BPROP with APROP. If APROP isn't NULL, return TRUE
  200. if APROP is updated. Otherwise, return TRUE if BPROP should be merged
  201. with ABFD. */
  202. static bool
  203. elf_merge_gnu_properties (struct bfd_link_info *info, bfd *abfd, bfd *bbfd,
  204. elf_property *aprop, elf_property *bprop)
  205. {
  206. const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  207. unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
  208. unsigned int number;
  209. bool updated;
  210. if (bed->merge_gnu_properties != NULL
  211. && pr_type >= GNU_PROPERTY_LOPROC
  212. && pr_type < GNU_PROPERTY_LOUSER)
  213. return bed->merge_gnu_properties (info, abfd, bbfd, aprop, bprop);
  214. switch (pr_type)
  215. {
  216. case GNU_PROPERTY_STACK_SIZE:
  217. if (aprop != NULL && bprop != NULL)
  218. {
  219. if (bprop->u.number > aprop->u.number)
  220. {
  221. aprop->u.number = bprop->u.number;
  222. return true;
  223. }
  224. break;
  225. }
  226. /* FALLTHROUGH */
  227. case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
  228. /* Return TRUE if APROP is NULL to indicate that BPROP should
  229. be added to ABFD. */
  230. return aprop == NULL;
  231. default:
  232. updated = false;
  233. if (pr_type >= GNU_PROPERTY_UINT32_OR_LO
  234. && pr_type <= GNU_PROPERTY_UINT32_OR_HI)
  235. {
  236. if (aprop != NULL && bprop != NULL)
  237. {
  238. number = aprop->u.number;
  239. aprop->u.number = number | bprop->u.number;
  240. /* Remove the property if all bits are empty. */
  241. if (aprop->u.number == 0)
  242. {
  243. aprop->pr_kind = property_remove;
  244. updated = true;
  245. }
  246. else
  247. updated = number != (unsigned int) aprop->u.number;
  248. }
  249. else
  250. {
  251. /* Only one of APROP and BPROP can be NULL. */
  252. if (aprop != NULL)
  253. {
  254. if (aprop->u.number == 0)
  255. {
  256. /* Remove APROP if all bits are empty. */
  257. aprop->pr_kind = property_remove;
  258. updated = true;
  259. }
  260. }
  261. else
  262. {
  263. /* Return TRUE if APROP is NULL and all bits of BPROP
  264. aren't empty to indicate that BPROP should be added
  265. to ABFD. */
  266. updated = bprop->u.number != 0;
  267. }
  268. }
  269. return updated;
  270. }
  271. else if (pr_type >= GNU_PROPERTY_UINT32_AND_LO
  272. && pr_type <= GNU_PROPERTY_UINT32_AND_HI)
  273. {
  274. /* Only one of APROP and BPROP can be NULL:
  275. 1. APROP & BPROP when both APROP and BPROP aren't NULL.
  276. 2. If APROP is NULL, remove x86 feature.
  277. 3. Otherwise, do nothing.
  278. */
  279. if (aprop != NULL && bprop != NULL)
  280. {
  281. number = aprop->u.number;
  282. aprop->u.number = number & bprop->u.number;
  283. updated = number != (unsigned int) aprop->u.number;
  284. /* Remove the property if all feature bits are cleared. */
  285. if (aprop->u.number == 0)
  286. aprop->pr_kind = property_remove;
  287. }
  288. else
  289. {
  290. /* There should be no AND properties since some input
  291. doesn't have them. */
  292. if (aprop != NULL)
  293. {
  294. aprop->pr_kind = property_remove;
  295. updated = true;
  296. }
  297. }
  298. return updated;
  299. }
  300. /* Never should happen. */
  301. abort ();
  302. }
  303. return false;
  304. }
  305. /* Return the property of TYPE on *LISTP and remove it from *LISTP if RM is
  306. true. Return NULL if not found. */
  307. static elf_property *
  308. elf_find_and_remove_property (elf_property_list **listp,
  309. unsigned int type, bool rm)
  310. {
  311. elf_property_list *list;
  312. for (list = *listp; list; list = list->next)
  313. {
  314. if (type == list->property.pr_type)
  315. {
  316. /* Remove this property. */
  317. if (rm)
  318. *listp = list->next;
  319. return &list->property;
  320. }
  321. else if (type < list->property.pr_type)
  322. break;
  323. listp = &list->next;
  324. }
  325. return NULL;
  326. }
  327. /* Merge GNU property list *LISTP in ABFD with FIRST_PBFD. */
  328. static void
  329. elf_merge_gnu_property_list (struct bfd_link_info *info, bfd *first_pbfd,
  330. bfd *abfd, elf_property_list **listp)
  331. {
  332. elf_property_list *p, **lastp;
  333. elf_property *pr;
  334. bool number_p;
  335. bfd_vma number = 0;
  336. /* Merge each GNU property in FIRST_PBFD with the one on *LISTP. */
  337. lastp = &elf_properties (first_pbfd);
  338. for (p = *lastp; p; p = p->next)
  339. if (p->property.pr_kind != property_remove)
  340. {
  341. if (p->property.pr_kind == property_number)
  342. {
  343. number_p = true;
  344. number = p->property.u.number;
  345. }
  346. else
  347. number_p = false;
  348. pr = elf_find_and_remove_property (listp, p->property.pr_type,
  349. true);
  350. /* Pass NULL to elf_merge_gnu_properties for the property which
  351. isn't on *LISTP. */
  352. elf_merge_gnu_properties (info, first_pbfd, abfd, &p->property, pr);
  353. if (p->property.pr_kind == property_remove)
  354. {
  355. if (info->has_map_file)
  356. {
  357. if (number_p)
  358. {
  359. if (pr != NULL)
  360. info->callbacks->minfo
  361. (_("Removed property %W to merge %pB (0x%v) "
  362. "and %pB (0x%v)\n"),
  363. (bfd_vma) p->property.pr_type, first_pbfd,
  364. number, abfd, pr->u.number);
  365. else
  366. info->callbacks->minfo
  367. (_("Removed property %W to merge %pB (0x%v) "
  368. "and %pB (not found)\n"),
  369. (bfd_vma) p->property.pr_type, first_pbfd,
  370. number, abfd);
  371. }
  372. else
  373. {
  374. if (pr != NULL)
  375. info->callbacks->minfo
  376. (_("Removed property %W to merge %pB and %pB\n"),
  377. (bfd_vma) p->property.pr_type, first_pbfd, abfd);
  378. else
  379. info->callbacks->minfo
  380. (_("Removed property %W to merge %pB and %pB "
  381. "(not found)\n"),
  382. (bfd_vma) p->property.pr_type, first_pbfd, abfd);
  383. }
  384. }
  385. /* Remove this property. */
  386. *lastp = p->next;
  387. continue;
  388. }
  389. else if (number_p)
  390. {
  391. if (pr != NULL)
  392. {
  393. if (p->property.u.number != number
  394. || p->property.u.number != pr->u.number)
  395. info->callbacks->minfo
  396. (_("Updated property %W (0x%v) to merge %pB (0x%v) "
  397. "and %pB (0x%v)\n"),
  398. (bfd_vma) p->property.pr_type, p->property.u.number,
  399. first_pbfd, number, abfd, pr->u.number);
  400. }
  401. else
  402. {
  403. if (p->property.u.number != number)
  404. info->callbacks->minfo
  405. (_("Updated property %W (%v) to merge %pB (0x%v) "
  406. "and %pB (not found)\n"),
  407. (bfd_vma) p->property.pr_type, p->property.u.number,
  408. first_pbfd, number, abfd);
  409. }
  410. }
  411. lastp = &p->next;
  412. }
  413. /* Merge the remaining properties on *LISTP with FIRST_PBFD. */
  414. for (p = *listp; p != NULL; p = p->next)
  415. {
  416. if (p->property.pr_kind == property_number)
  417. {
  418. number_p = true;
  419. number = p->property.u.number;
  420. }
  421. else
  422. number_p = false;
  423. if (elf_merge_gnu_properties (info, first_pbfd, abfd, NULL, &p->property))
  424. {
  425. if (p->property.pr_type == GNU_PROPERTY_NO_COPY_ON_PROTECTED)
  426. elf_has_no_copy_on_protected (first_pbfd) = true;
  427. pr = _bfd_elf_get_property (first_pbfd, p->property.pr_type,
  428. p->property.pr_datasz);
  429. /* It must be a new property. */
  430. if (pr->pr_kind != property_unknown)
  431. abort ();
  432. /* Add a new property. */
  433. *pr = p->property;
  434. }
  435. else
  436. {
  437. pr = elf_find_and_remove_property (&elf_properties (first_pbfd),
  438. p->property.pr_type,
  439. false);
  440. if (pr == NULL)
  441. {
  442. if (number_p)
  443. info->callbacks->minfo
  444. (_("Removed property %W to merge %pB (not found) and "
  445. "%pB (0x%v)\n"),
  446. (bfd_vma) p->property.pr_type, first_pbfd, abfd,
  447. number);
  448. else
  449. info->callbacks->minfo
  450. (_("Removed property %W to merge %pB and %pB\n"),
  451. (bfd_vma) p->property.pr_type, first_pbfd, abfd);
  452. }
  453. else if (pr->pr_kind != property_remove)
  454. abort ();
  455. }
  456. }
  457. }
  458. /* Get GNU property section size. */
  459. static bfd_size_type
  460. elf_get_gnu_property_section_size (elf_property_list *list,
  461. unsigned int align_size)
  462. {
  463. bfd_size_type size;
  464. unsigned int descsz;
  465. /* Compute the output section size. */
  466. descsz = offsetof (Elf_External_Note, name[sizeof "GNU"]);
  467. descsz = (descsz + 3) & -(unsigned int) 4;
  468. size = descsz;
  469. for (; list != NULL; list = list->next)
  470. {
  471. unsigned int datasz;
  472. /* Check if this property should be skipped. */
  473. if (list->property.pr_kind == property_remove)
  474. continue;
  475. /* There are 4 byte type + 4 byte datasz for each property. */
  476. if (list->property.pr_type == GNU_PROPERTY_STACK_SIZE)
  477. datasz = align_size;
  478. else
  479. datasz = list->property.pr_datasz;
  480. size += 4 + 4 + datasz;
  481. /* Align each property. */
  482. size = (size + (align_size - 1)) & ~(align_size - 1);
  483. }
  484. return size;
  485. }
  486. /* Write GNU properties. */
  487. static void
  488. elf_write_gnu_properties (struct bfd_link_info *info,
  489. bfd *abfd, bfd_byte *contents,
  490. elf_property_list *list, unsigned int size,
  491. unsigned int align_size)
  492. {
  493. unsigned int descsz;
  494. unsigned int datasz;
  495. Elf_External_Note *e_note;
  496. e_note = (Elf_External_Note *) contents;
  497. descsz = offsetof (Elf_External_Note, name[sizeof "GNU"]);
  498. descsz = (descsz + 3) & -(unsigned int) 4;
  499. bfd_h_put_32 (abfd, sizeof "GNU", &e_note->namesz);
  500. bfd_h_put_32 (abfd, size - descsz, &e_note->descsz);
  501. bfd_h_put_32 (abfd, NT_GNU_PROPERTY_TYPE_0, &e_note->type);
  502. memcpy (e_note->name, "GNU", sizeof "GNU");
  503. size = descsz;
  504. for (; list != NULL; list = list->next)
  505. {
  506. /* Check if this property should be skipped. */
  507. if (list->property.pr_kind == property_remove)
  508. continue;
  509. /* There are 4 byte type + 4 byte datasz for each property. */
  510. if (list->property.pr_type == GNU_PROPERTY_STACK_SIZE)
  511. datasz = align_size;
  512. else
  513. datasz = list->property.pr_datasz;
  514. bfd_h_put_32 (abfd, list->property.pr_type, contents + size);
  515. bfd_h_put_32 (abfd, datasz, contents + size + 4);
  516. size += 4 + 4;
  517. /* Write out property value. */
  518. switch (list->property.pr_kind)
  519. {
  520. case property_number:
  521. switch (datasz)
  522. {
  523. default:
  524. /* Never should happen. */
  525. abort ();
  526. case 0:
  527. break;
  528. case 4:
  529. /* Save the pointer to GNU_PROPERTY_1_NEEDED so that it
  530. can be updated later if needed. */
  531. if (info != NULL
  532. && list->property.pr_type == GNU_PROPERTY_1_NEEDED)
  533. info->needed_1_p = contents + size;
  534. bfd_h_put_32 (abfd, list->property.u.number,
  535. contents + size);
  536. break;
  537. case 8:
  538. bfd_h_put_64 (abfd, list->property.u.number,
  539. contents + size);
  540. break;
  541. }
  542. break;
  543. default:
  544. /* Never should happen. */
  545. abort ();
  546. }
  547. size += datasz;
  548. /* Align each property. */
  549. size = (size + (align_size - 1)) & ~ (align_size - 1);
  550. }
  551. }
  552. /* Set up GNU properties. Return the first relocatable ELF input with
  553. GNU properties if found. Otherwise, return NULL. */
  554. bfd *
  555. _bfd_elf_link_setup_gnu_properties (struct bfd_link_info *info)
  556. {
  557. bfd *abfd, *first_pbfd = NULL, *elf_bfd = NULL;
  558. elf_property_list *list;
  559. asection *sec;
  560. bool has_properties = false;
  561. const struct elf_backend_data *bed
  562. = get_elf_backend_data (info->output_bfd);
  563. unsigned int elfclass = bed->s->elfclass;
  564. int elf_machine_code = bed->elf_machine_code;
  565. elf_property *p;
  566. /* Find the first relocatable ELF input with GNU properties. */
  567. for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
  568. if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
  569. && (abfd->flags & DYNAMIC) == 0
  570. && (elf_machine_code
  571. == get_elf_backend_data (abfd)->elf_machine_code)
  572. && (elfclass == get_elf_backend_data (abfd)->s->elfclass))
  573. {
  574. /* Ignore GNU properties from ELF objects with different machine
  575. code or class. Also skip objects without a GNU_PROPERTY note
  576. section. */
  577. elf_bfd = abfd;
  578. if (elf_properties (abfd) != NULL)
  579. {
  580. has_properties = true;
  581. if (bfd_get_section_by_name (abfd,
  582. NOTE_GNU_PROPERTY_SECTION_NAME)
  583. != NULL)
  584. {
  585. /* Keep .note.gnu.property section in FIRST_PBFD. */
  586. first_pbfd = abfd;
  587. break;
  588. }
  589. }
  590. }
  591. if (info->indirect_extern_access > 0 && elf_bfd != NULL)
  592. {
  593. /* Support -z indirect-extern-access. */
  594. if (first_pbfd == NULL)
  595. {
  596. sec = bfd_make_section_with_flags (elf_bfd,
  597. NOTE_GNU_PROPERTY_SECTION_NAME,
  598. (SEC_ALLOC
  599. | SEC_LOAD
  600. | SEC_IN_MEMORY
  601. | SEC_READONLY
  602. | SEC_HAS_CONTENTS
  603. | SEC_DATA));
  604. if (sec == NULL)
  605. info->callbacks->einfo (_("%F%P: failed to create GNU property section\n"));
  606. if (!bfd_set_section_alignment (sec,
  607. elfclass == ELFCLASS64 ? 3 : 2))
  608. info->callbacks->einfo (_("%F%pA: failed to align section\n"),
  609. sec);
  610. elf_section_type (sec) = SHT_NOTE;
  611. first_pbfd = elf_bfd;
  612. has_properties = true;
  613. }
  614. p = _bfd_elf_get_property (first_pbfd, GNU_PROPERTY_1_NEEDED, 4);
  615. if (p->pr_kind == property_unknown)
  616. {
  617. /* Create GNU_PROPERTY_1_NEEDED. */
  618. p->u.number
  619. = GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
  620. p->pr_kind = property_number;
  621. }
  622. else
  623. p->u.number
  624. |= GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
  625. }
  626. /* Do nothing if there is no .note.gnu.property section. */
  627. if (!has_properties)
  628. return NULL;
  629. /* Merge .note.gnu.property sections. */
  630. info->callbacks->minfo (_("\n"));
  631. info->callbacks->minfo (_("Merging program properties\n"));
  632. info->callbacks->minfo (_("\n"));
  633. for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link.next)
  634. if (abfd != first_pbfd
  635. && (abfd->flags & (DYNAMIC | BFD_PLUGIN | BFD_LINKER_CREATED)) == 0)
  636. {
  637. elf_property_list *null_ptr = NULL;
  638. elf_property_list **listp = &null_ptr;
  639. /* Merge .note.gnu.property section in relocatable ELF input. */
  640. if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
  641. {
  642. list = elf_properties (abfd);
  643. /* Ignore GNU properties from ELF objects with different
  644. machine code. */
  645. if (list != NULL
  646. && (elf_machine_code
  647. == get_elf_backend_data (abfd)->elf_machine_code))
  648. listp = &elf_properties (abfd);
  649. }
  650. else
  651. list = NULL;
  652. /* Merge properties with FIRST_PBFD. FIRST_PBFD can be NULL
  653. when all properties are from ELF objects with different
  654. machine code or class. */
  655. if (first_pbfd != NULL)
  656. elf_merge_gnu_property_list (info, first_pbfd, abfd, listp);
  657. if (list != NULL)
  658. {
  659. /* Discard the .note.gnu.property section in this bfd. */
  660. sec = bfd_get_section_by_name (abfd,
  661. NOTE_GNU_PROPERTY_SECTION_NAME);
  662. if (sec != NULL)
  663. sec->output_section = bfd_abs_section_ptr;
  664. }
  665. }
  666. /* Rewrite .note.gnu.property section so that GNU properties are
  667. always sorted by type even if input GNU properties aren't sorted. */
  668. if (first_pbfd != NULL)
  669. {
  670. bfd_size_type size;
  671. bfd_byte *contents;
  672. unsigned int align_size = elfclass == ELFCLASS64 ? 8 : 4;
  673. sec = bfd_get_section_by_name (first_pbfd,
  674. NOTE_GNU_PROPERTY_SECTION_NAME);
  675. BFD_ASSERT (sec != NULL);
  676. /* Update stack size in .note.gnu.property with -z stack-size=N
  677. if N > 0. */
  678. if (info->stacksize > 0)
  679. {
  680. bfd_vma stacksize = info->stacksize;
  681. p = _bfd_elf_get_property (first_pbfd, GNU_PROPERTY_STACK_SIZE,
  682. align_size);
  683. if (p->pr_kind == property_unknown)
  684. {
  685. /* Create GNU_PROPERTY_STACK_SIZE. */
  686. p->u.number = stacksize;
  687. p->pr_kind = property_number;
  688. }
  689. else if (stacksize > p->u.number)
  690. p->u.number = stacksize;
  691. }
  692. else if (elf_properties (first_pbfd) == NULL)
  693. {
  694. /* Discard .note.gnu.property section if all properties have
  695. been removed. */
  696. sec->output_section = bfd_abs_section_ptr;
  697. return NULL;
  698. }
  699. /* Fix up GNU properties. */
  700. if (bed->fixup_gnu_properties)
  701. bed->fixup_gnu_properties (info, &elf_properties (first_pbfd));
  702. if (elf_properties (first_pbfd) == NULL)
  703. {
  704. /* Discard .note.gnu.property section if all properties have
  705. been removed. */
  706. sec->output_section = bfd_abs_section_ptr;
  707. return NULL;
  708. }
  709. /* Compute the section size. */
  710. list = elf_properties (first_pbfd);
  711. size = elf_get_gnu_property_section_size (list, align_size);
  712. /* Update .note.gnu.property section now. */
  713. sec->size = size;
  714. contents = (bfd_byte *) bfd_zalloc (first_pbfd, size);
  715. if (info->indirect_extern_access <= 0)
  716. {
  717. /* Get GNU_PROPERTY_1_NEEDED properties. */
  718. p = elf_find_and_remove_property (&elf_properties (first_pbfd),
  719. GNU_PROPERTY_1_NEEDED, false);
  720. if (p != NULL)
  721. {
  722. if (info->indirect_extern_access < 0)
  723. {
  724. /* Set indirect_extern_access to 1 to indicate that
  725. it is turned on by input properties. */
  726. if ((p->u.number
  727. & GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS)
  728. != 0)
  729. info->indirect_extern_access = 1;
  730. }
  731. else
  732. /* Turn off indirect external access. */
  733. p->u.number
  734. &= ~GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS;
  735. }
  736. }
  737. elf_write_gnu_properties (info, first_pbfd, contents, list, size,
  738. align_size);
  739. /* Cache the section contents for elf_link_input_bfd. */
  740. elf_section_data (sec)->this_hdr.contents = contents;
  741. /* If GNU_PROPERTY_NO_COPY_ON_PROTECTED is set, protected data
  742. symbol is defined in the shared object. */
  743. if (elf_has_no_copy_on_protected (first_pbfd))
  744. info->extern_protected_data = false;
  745. if (info->indirect_extern_access > 0)
  746. {
  747. /* For indirect external access, don't generate copy
  748. relocations. NB: Set to nocopyreloc to 2 to indicate
  749. that it is implied by indirect_extern_access. */
  750. info->nocopyreloc = 2;
  751. info->extern_protected_data = false;
  752. }
  753. }
  754. return first_pbfd;
  755. }
  756. /* Convert GNU property size. */
  757. bfd_size_type
  758. _bfd_elf_convert_gnu_property_size (bfd *ibfd, bfd *obfd)
  759. {
  760. unsigned int align_size;
  761. const struct elf_backend_data *bed;
  762. elf_property_list *list = elf_properties (ibfd);
  763. bed = get_elf_backend_data (obfd);
  764. align_size = bed->s->elfclass == ELFCLASS64 ? 8 : 4;
  765. /* Get the output .note.gnu.property section size. */
  766. return elf_get_gnu_property_section_size (list, align_size);
  767. }
  768. /* Convert GNU properties. */
  769. bool
  770. _bfd_elf_convert_gnu_properties (bfd *ibfd, asection *isec,
  771. bfd *obfd, bfd_byte **ptr,
  772. bfd_size_type *ptr_size)
  773. {
  774. unsigned int size;
  775. bfd_byte *contents;
  776. unsigned int align_shift;
  777. const struct elf_backend_data *bed;
  778. elf_property_list *list = elf_properties (ibfd);
  779. bed = get_elf_backend_data (obfd);
  780. align_shift = bed->s->elfclass == ELFCLASS64 ? 3 : 2;
  781. /* Get the output .note.gnu.property section size. */
  782. size = bfd_section_size (isec->output_section);
  783. /* Update the output .note.gnu.property section alignment. */
  784. bfd_set_section_alignment (isec->output_section, align_shift);
  785. if (size > bfd_section_size (isec))
  786. {
  787. contents = (bfd_byte *) bfd_malloc (size);
  788. if (contents == NULL)
  789. return false;
  790. free (*ptr);
  791. *ptr = contents;
  792. }
  793. else
  794. contents = *ptr;
  795. *ptr_size = size;
  796. /* Generate the output .note.gnu.property section. */
  797. elf_write_gnu_properties (NULL, ibfd, contents, list, size,
  798. 1 << align_shift);
  799. return true;
  800. }