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