Fix regression from change
[binutils.git] / ld / emultempl / tic6xdsbt.em
blobe2870053d75647e378985a2b9ae8ced888b19400
1 # This shell script emits a C file. -*- C -*-
2 #   Copyright 2011 Free Software Foundation, Inc.
4 # This file is part of the GNU Binutils.
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.
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.
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.
22 # This file is sourced from elf32.em, and defines extra C6X DSBT specific
23 # features.
25 fragment <<EOF
26 #include "ldctor.h"
27 #include "elf32-tic6x.h"
29 static struct elf32_tic6x_params params =
31   0, 64
34 static int merge_exidx_entries = -1;
36 static int
37 is_tic6x_target (void)
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;
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);
54 /* Pass params to backend.  */
56 static void
57 tic6x_after_open (void)
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, &params);
67     }
69   gld${EMULATION_NAME}_after_open ();
72 static int
73 compare_output_sec_vma (const void *a, const void *b)
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;
94 static void
95 gld${EMULATION_NAME}_after_allocation (void)
97   int layout_changed = 0;
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;
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;
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 != ELF_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                     }
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     }
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;
155   gld${EMULATION_NAME}_map_segments (layout_changed);
159 # This code gets inserted into the generic elf32.sc linker script
160 # and allows us to define our own command line switches.
161 PARSE_AND_LIST_PROLOGUE='
162 #define OPTION_DSBT_INDEX               300
163 #define OPTION_DSBT_SIZE                301
164 #define OPTION_NO_MERGE_EXIDX_ENTRIES   302
167 PARSE_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 },
173 PARSE_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"));
181 PARSE_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;
206 LDEMUL_AFTER_OPEN=tic6x_after_open
207 LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation