1# This shell script emits a C file. -*- C -*- 2# Copyright 2011, 2012 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 22# This file is sourced from elf32.em, and defines extra C6X DSBT specific 23# features. 24# 25fragment <<EOF 26#include "ldctor.h" 27#include "elf32-tic6x.h" 28 29static struct elf32_tic6x_params params = 30{ 31 0, 64 32}; 33 34static int merge_exidx_entries = -1; 35 36static int 37is_tic6x_target (void) 38{ 39 extern const bfd_target bfd_elf32_tic6x_le_vec; 40 extern const bfd_target bfd_elf32_tic6x_be_vec; 41 extern const bfd_target bfd_elf32_tic6x_linux_le_vec; 42 extern const bfd_target bfd_elf32_tic6x_linux_be_vec; 43 extern const bfd_target bfd_elf32_tic6x_elf_le_vec; 44 extern const bfd_target bfd_elf32_tic6x_elf_be_vec; 45 46 return (link_info.output_bfd->xvec == &bfd_elf32_tic6x_le_vec 47 || link_info.output_bfd->xvec == &bfd_elf32_tic6x_be_vec 48 || link_info.output_bfd->xvec == &bfd_elf32_tic6x_linux_le_vec 49 || link_info.output_bfd->xvec == &bfd_elf32_tic6x_linux_be_vec 50 || link_info.output_bfd->xvec == &bfd_elf32_tic6x_elf_le_vec 51 || link_info.output_bfd->xvec == &bfd_elf32_tic6x_elf_be_vec); 52} 53 54/* Pass params to backend. */ 55 56static void 57tic6x_after_open (void) 58{ 59 if (is_tic6x_target ()) 60 { 61 if (params.dsbt_index >= params.dsbt_size) 62 { 63 einfo (_("%P%F: invalid --dsbt-index %d, outside DSBT size.\n"), 64 params.dsbt_index); 65 } 66 elf32_tic6x_setup (&link_info, ¶ms); 67 } 68 69 gld${EMULATION_NAME}_after_open (); 70} 71 72static int 73compare_output_sec_vma (const void *a, const void *b) 74{ 75 asection *asec = *(asection **) a, *bsec = *(asection **) b; 76 asection *aout = asec->output_section, *bout = bsec->output_section; 77 bfd_vma avma, bvma; 78 79 /* If there's no output section for some reason, compare equal. */ 80 if (!aout || !bout) 81 return 0; 82 83 avma = aout->vma + asec->output_offset; 84 bvma = bout->vma + bsec->output_offset; 85 86 if (avma > bvma) 87 return 1; 88 else if (avma < bvma) 89 return -1; 90 91 return 0; 92} 93 94static void 95gld${EMULATION_NAME}_after_allocation (void) 96{ 97 int layout_changed = 0; 98 99 if (!link_info.relocatable) 100 { 101 /* Build a sorted list of input text sections, then use that to process 102 the unwind table index. */ 103 unsigned int list_size = 10; 104 asection **sec_list = (asection **) 105 xmalloc (list_size * sizeof (asection *)); 106 unsigned int sec_count = 0; 107 108 LANG_FOR_EACH_INPUT_STATEMENT (is) 109 { 110 bfd *abfd = is->the_bfd; 111 asection *sec; 112 113 if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) 114 continue; 115 116 for (sec = abfd->sections; sec != NULL; sec = sec->next) 117 { 118 asection *out_sec = sec->output_section; 119 120 if (out_sec 121 && elf_section_data (sec) 122 && elf_section_type (sec) == SHT_PROGBITS 123 && (elf_section_flags (sec) & SHF_EXECINSTR) != 0 124 && (sec->flags & SEC_EXCLUDE) == 0 125 && sec->sec_info_type != SEC_INFO_TYPE_JUST_SYMS 126 && out_sec != bfd_abs_section_ptr) 127 { 128 if (sec_count == list_size) 129 { 130 list_size *= 2; 131 sec_list = (asection **) 132 xrealloc (sec_list, list_size * sizeof (asection *)); 133 } 134 135 sec_list[sec_count++] = sec; 136 } 137 } 138 } 139 140 qsort (sec_list, sec_count, sizeof (asection *), &compare_output_sec_vma); 141 142 if (elf32_tic6x_fix_exidx_coverage (sec_list, sec_count, &link_info, 143 merge_exidx_entries)) 144 layout_changed = 1; 145 146 free (sec_list); 147 } 148 149 /* bfd_elf32_discard_info just plays with debugging sections, 150 ie. doesn't affect any code, so we can delay resizing the 151 sections. */ 152 if (bfd_elf_discard_info (link_info.output_bfd, & link_info)) 153 layout_changed = 1; 154 155 gld${EMULATION_NAME}_map_segments (layout_changed); 156} 157EOF 158 159# This code gets inserted into the generic elf32.sc linker script 160# and allows us to define our own command line switches. 161PARSE_AND_LIST_PROLOGUE=' 162#define OPTION_DSBT_INDEX 300 163#define OPTION_DSBT_SIZE 301 164#define OPTION_NO_MERGE_EXIDX_ENTRIES 302 165' 166 167PARSE_AND_LIST_LONGOPTS=' 168 {"dsbt-index", required_argument, NULL, OPTION_DSBT_INDEX}, 169 {"dsbt-size", required_argument, NULL, OPTION_DSBT_SIZE}, 170 { "no-merge-exidx-entries", no_argument, NULL, OPTION_NO_MERGE_EXIDX_ENTRIES }, 171' 172 173PARSE_AND_LIST_OPTIONS=' 174 fprintf (file, _(" --dsbt-index <index>\n")); 175 fprintf (file, _("\t\t\tUse this as the DSBT index for the output object\n")); 176 fprintf (file, _(" --dsbt-size <index>\n")); 177 fprintf (file, _("\t\t\tUse this as the number of entries in the DSBT table\n")); 178 fprintf (file, _(" --no-merge-exidx-entries Disable merging exidx entries\n")); 179' 180 181PARSE_AND_LIST_ARGS_CASES=' 182 case OPTION_DSBT_INDEX: 183 { 184 char *end; 185 params.dsbt_index = strtol (optarg, &end, 0); 186 if (*end == 0 187 && params.dsbt_index >= 0 && params.dsbt_index < 0x7fff) 188 break; 189 einfo (_("%P%F: invalid --dsbt-index %s\n"), optarg); 190 } 191 break; 192 case OPTION_DSBT_SIZE: 193 { 194 char *end; 195 params.dsbt_size = strtol (optarg, &end, 0); 196 if (*end == 0 197 && params.dsbt_size >= 0 && params.dsbt_size < 0x7fff) 198 break; 199 einfo (_("%P%F: invalid --dsbt-size %s\n"), optarg); 200 } 201 break; 202 case OPTION_NO_MERGE_EXIDX_ENTRIES: 203 merge_exidx_entries = 0; 204' 205 206LDEMUL_AFTER_OPEN=tic6x_after_open 207LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation 208