1# This shell script emits a C file. -*- C -*- 2# Copyright (C) 2011-2014 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 tic6x_elf32_le_vec; 40 extern const bfd_target tic6x_elf32_be_vec; 41 extern const bfd_target tic6x_elf32_linux_le_vec; 42 extern const bfd_target tic6x_elf32_linux_be_vec; 43 extern const bfd_target tic6x_elf32_c6000_le_vec; 44 extern const bfd_target tic6x_elf32_c6000_be_vec; 45 46 return (link_info.output_bfd->xvec == &tic6x_elf32_le_vec 47 || link_info.output_bfd->xvec == &tic6x_elf32_be_vec 48 || link_info.output_bfd->xvec == &tic6x_elf32_linux_le_vec 49 || link_info.output_bfd->xvec == &tic6x_elf32_linux_be_vec 50 || link_info.output_bfd->xvec == &tic6x_elf32_c6000_le_vec 51 || link_info.output_bfd->xvec == &tic6x_elf32_c6000_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 int ret; 99 100 if (!link_info.relocatable) 101 { 102 /* Build a sorted list of input text sections, then use that to process 103 the unwind table index. */ 104 unsigned int list_size = 10; 105 asection **sec_list = (asection **) 106 xmalloc (list_size * sizeof (asection *)); 107 unsigned int sec_count = 0; 108 109 LANG_FOR_EACH_INPUT_STATEMENT (is) 110 { 111 bfd *abfd = is->the_bfd; 112 asection *sec; 113 114 if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) 115 continue; 116 117 for (sec = abfd->sections; sec != NULL; sec = sec->next) 118 { 119 asection *out_sec = sec->output_section; 120 121 if (out_sec 122 && elf_section_data (sec) 123 && elf_section_type (sec) == SHT_PROGBITS 124 && (elf_section_flags (sec) & SHF_EXECINSTR) != 0 125 && (sec->flags & SEC_EXCLUDE) == 0 126 && sec->sec_info_type != SEC_INFO_TYPE_JUST_SYMS 127 && out_sec != bfd_abs_section_ptr) 128 { 129 if (sec_count == list_size) 130 { 131 list_size *= 2; 132 sec_list = (asection **) 133 xrealloc (sec_list, list_size * sizeof (asection *)); 134 } 135 136 sec_list[sec_count++] = sec; 137 } 138 } 139 } 140 141 qsort (sec_list, sec_count, sizeof (asection *), &compare_output_sec_vma); 142 143 if (elf32_tic6x_fix_exidx_coverage (sec_list, sec_count, &link_info, 144 merge_exidx_entries)) 145 layout_changed = 1; 146 147 free (sec_list); 148 } 149 150 /* bfd_elf32_discard_info just plays with debugging sections, 151 ie. doesn't affect any code, so we can delay resizing the 152 sections. */ 153 ret = bfd_elf_discard_info (link_info.output_bfd, & link_info); 154 if (ret < 0) 155 { 156 einfo ("%X%P: .eh_frame/.stab edit: %E\n"); 157 return; 158 } 159 else if (ret > 0) 160 layout_changed = 1; 161 162 gld${EMULATION_NAME}_map_segments (layout_changed); 163} 164EOF 165 166# This code gets inserted into the generic elf32.sc linker script 167# and allows us to define our own command line switches. 168PARSE_AND_LIST_PROLOGUE=' 169#define OPTION_DSBT_INDEX 300 170#define OPTION_DSBT_SIZE 301 171#define OPTION_NO_MERGE_EXIDX_ENTRIES 302 172' 173 174PARSE_AND_LIST_LONGOPTS=' 175 {"dsbt-index", required_argument, NULL, OPTION_DSBT_INDEX}, 176 {"dsbt-size", required_argument, NULL, OPTION_DSBT_SIZE}, 177 { "no-merge-exidx-entries", no_argument, NULL, OPTION_NO_MERGE_EXIDX_ENTRIES }, 178' 179 180PARSE_AND_LIST_OPTIONS=' 181 fprintf (file, _(" --dsbt-index <index>\n")); 182 fprintf (file, _("\t\t\tUse this as the DSBT index for the output object\n")); 183 fprintf (file, _(" --dsbt-size <index>\n")); 184 fprintf (file, _("\t\t\tUse this as the number of entries in the DSBT table\n")); 185 fprintf (file, _(" --no-merge-exidx-entries Disable merging exidx entries\n")); 186' 187 188PARSE_AND_LIST_ARGS_CASES=' 189 case OPTION_DSBT_INDEX: 190 { 191 char *end; 192 params.dsbt_index = strtol (optarg, &end, 0); 193 if (*end == 0 194 && params.dsbt_index >= 0 && params.dsbt_index < 0x7fff) 195 break; 196 einfo (_("%P%F: invalid --dsbt-index %s\n"), optarg); 197 } 198 break; 199 case OPTION_DSBT_SIZE: 200 { 201 char *end; 202 params.dsbt_size = strtol (optarg, &end, 0); 203 if (*end == 0 204 && params.dsbt_size >= 0 && params.dsbt_size < 0x7fff) 205 break; 206 einfo (_("%P%F: invalid --dsbt-size %s\n"), optarg); 207 } 208 break; 209 case OPTION_NO_MERGE_EXIDX_ENTRIES: 210 merge_exidx_entries = 0; 211' 212 213LDEMUL_AFTER_OPEN=tic6x_after_open 214LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation 215