tic6xdsbt.em 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. # This shell script emits a C file. -*- C -*-
  2. # Copyright (C) 2011-2015 Free Software Foundation, Inc.
  3. #
  4. # This file is part of the GNU Binutils.
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program; if not, write to the Free Software
  18. # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  19. # MA 02110-1301, USA.
  20. #
  21. # This file is sourced from elf32.em, and defines extra C6X DSBT specific
  22. # features.
  23. #
  24. fragment <<EOF
  25. #include "ldctor.h"
  26. #include "elf32-tic6x.h"
  27. static struct elf32_tic6x_params params =
  28. {
  29. 0, 64
  30. };
  31. static int merge_exidx_entries = -1;
  32. static int
  33. is_tic6x_target (void)
  34. {
  35. extern const bfd_target tic6x_elf32_le_vec;
  36. extern const bfd_target tic6x_elf32_be_vec;
  37. extern const bfd_target tic6x_elf32_linux_le_vec;
  38. extern const bfd_target tic6x_elf32_linux_be_vec;
  39. extern const bfd_target tic6x_elf32_c6000_le_vec;
  40. extern const bfd_target tic6x_elf32_c6000_be_vec;
  41. return (link_info.output_bfd->xvec == &tic6x_elf32_le_vec
  42. || link_info.output_bfd->xvec == &tic6x_elf32_be_vec
  43. || link_info.output_bfd->xvec == &tic6x_elf32_linux_le_vec
  44. || link_info.output_bfd->xvec == &tic6x_elf32_linux_be_vec
  45. || link_info.output_bfd->xvec == &tic6x_elf32_c6000_le_vec
  46. || link_info.output_bfd->xvec == &tic6x_elf32_c6000_be_vec);
  47. }
  48. /* Pass params to backend. */
  49. static void
  50. tic6x_after_open (void)
  51. {
  52. if (is_tic6x_target ())
  53. {
  54. if (params.dsbt_index >= params.dsbt_size)
  55. {
  56. einfo (_("%P%F: invalid --dsbt-index %d, outside DSBT size.\n"),
  57. params.dsbt_index);
  58. }
  59. elf32_tic6x_setup (&link_info, &params);
  60. }
  61. gld${EMULATION_NAME}_after_open ();
  62. }
  63. static int
  64. compare_output_sec_vma (const void *a, const void *b)
  65. {
  66. asection *asec = *(asection **) a, *bsec = *(asection **) b;
  67. asection *aout = asec->output_section, *bout = bsec->output_section;
  68. bfd_vma avma, bvma;
  69. /* If there's no output section for some reason, compare equal. */
  70. if (!aout || !bout)
  71. return 0;
  72. avma = aout->vma + asec->output_offset;
  73. bvma = bout->vma + bsec->output_offset;
  74. if (avma > bvma)
  75. return 1;
  76. else if (avma < bvma)
  77. return -1;
  78. return 0;
  79. }
  80. static void
  81. gld${EMULATION_NAME}_after_allocation (void)
  82. {
  83. int layout_changed = 0;
  84. int ret;
  85. if (!bfd_link_relocatable (&link_info))
  86. {
  87. /* Build a sorted list of input text sections, then use that to process
  88. the unwind table index. */
  89. unsigned int list_size = 10;
  90. asection **sec_list = (asection **)
  91. xmalloc (list_size * sizeof (asection *));
  92. unsigned int sec_count = 0;
  93. LANG_FOR_EACH_INPUT_STATEMENT (is)
  94. {
  95. bfd *abfd = is->the_bfd;
  96. asection *sec;
  97. if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
  98. continue;
  99. for (sec = abfd->sections; sec != NULL; sec = sec->next)
  100. {
  101. asection *out_sec = sec->output_section;
  102. if (out_sec
  103. && elf_section_data (sec)
  104. && elf_section_type (sec) == SHT_PROGBITS
  105. && (elf_section_flags (sec) & SHF_EXECINSTR) != 0
  106. && (sec->flags & SEC_EXCLUDE) == 0
  107. && sec->sec_info_type != SEC_INFO_TYPE_JUST_SYMS
  108. && out_sec != bfd_abs_section_ptr)
  109. {
  110. if (sec_count == list_size)
  111. {
  112. list_size *= 2;
  113. sec_list = (asection **)
  114. xrealloc (sec_list, list_size * sizeof (asection *));
  115. }
  116. sec_list[sec_count++] = sec;
  117. }
  118. }
  119. }
  120. qsort (sec_list, sec_count, sizeof (asection *), &compare_output_sec_vma);
  121. if (elf32_tic6x_fix_exidx_coverage (sec_list, sec_count, &link_info,
  122. merge_exidx_entries))
  123. layout_changed = 1;
  124. free (sec_list);
  125. }
  126. /* bfd_elf32_discard_info just plays with debugging sections,
  127. ie. doesn't affect any code, so we can delay resizing the
  128. sections. */
  129. ret = bfd_elf_discard_info (link_info.output_bfd, & link_info);
  130. if (ret < 0)
  131. {
  132. einfo ("%X%P: .eh_frame/.stab edit: %E\n");
  133. return;
  134. }
  135. else if (ret > 0)
  136. layout_changed = 1;
  137. gld${EMULATION_NAME}_map_segments (layout_changed);
  138. }
  139. EOF
  140. # This code gets inserted into the generic elf32.sc linker script
  141. # and allows us to define our own command line switches.
  142. PARSE_AND_LIST_PROLOGUE='
  143. #define OPTION_DSBT_INDEX 300
  144. #define OPTION_DSBT_SIZE 301
  145. #define OPTION_NO_MERGE_EXIDX_ENTRIES 302
  146. '
  147. PARSE_AND_LIST_LONGOPTS='
  148. {"dsbt-index", required_argument, NULL, OPTION_DSBT_INDEX},
  149. {"dsbt-size", required_argument, NULL, OPTION_DSBT_SIZE},
  150. { "no-merge-exidx-entries", no_argument, NULL, OPTION_NO_MERGE_EXIDX_ENTRIES },
  151. '
  152. PARSE_AND_LIST_OPTIONS='
  153. fprintf (file, _(" --dsbt-index <index>\n"));
  154. fprintf (file, _("\t\t\tUse this as the DSBT index for the output object\n"));
  155. fprintf (file, _(" --dsbt-size <index>\n"));
  156. fprintf (file, _("\t\t\tUse this as the number of entries in the DSBT table\n"));
  157. fprintf (file, _(" --no-merge-exidx-entries Disable merging exidx entries\n"));
  158. '
  159. PARSE_AND_LIST_ARGS_CASES='
  160. case OPTION_DSBT_INDEX:
  161. {
  162. char *end;
  163. params.dsbt_index = strtol (optarg, &end, 0);
  164. if (*end == 0
  165. && params.dsbt_index >= 0 && params.dsbt_index < 0x7fff)
  166. break;
  167. einfo (_("%P%F: invalid --dsbt-index %s\n"), optarg);
  168. }
  169. break;
  170. case OPTION_DSBT_SIZE:
  171. {
  172. char *end;
  173. params.dsbt_size = strtol (optarg, &end, 0);
  174. if (*end == 0
  175. && params.dsbt_size >= 0 && params.dsbt_size < 0x7fff)
  176. break;
  177. einfo (_("%P%F: invalid --dsbt-size %s\n"), optarg);
  178. }
  179. break;
  180. case OPTION_NO_MERGE_EXIDX_ENTRIES:
  181. merge_exidx_entries = 0;
  182. '
  183. LDEMUL_AFTER_OPEN=tic6x_after_open
  184. LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation