elf32-ft32.c revision 1.1.1.7 1 1.1 christos /* ft32-specific support for 32-bit ELF.
2 1.1.1.7 christos Copyright (C) 2013-2024 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos Copied from elf32-moxie.c which is..
5 1.1.1.7 christos Copyright (C) 2009-2024 Free Software Foundation, Inc.
6 1.1 christos Free Software Foundation, Inc.
7 1.1 christos
8 1.1 christos This file is part of BFD, the Binary File Descriptor library.
9 1.1 christos
10 1.1 christos This program is free software; you can redistribute it and/or modify
11 1.1 christos it under the terms of the GNU General Public License as published by
12 1.1 christos the Free Software Foundation; either version 3 of the License, or
13 1.1 christos (at your option) any later version.
14 1.1 christos
15 1.1 christos This program is distributed in the hope that it will be useful,
16 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
17 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 1.1 christos GNU General Public License for more details.
19 1.1 christos
20 1.1 christos You should have received a copy of the GNU General Public License
21 1.1 christos along with this program; if not, write to the Free Software
22 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 1.1 christos MA 02110-1301, USA. */
24 1.1 christos
25 1.1 christos #include "sysdep.h"
26 1.1 christos #include "bfd.h"
27 1.1 christos #include "libbfd.h"
28 1.1 christos #include "elf-bfd.h"
29 1.1 christos #include "elf/ft32.h"
30 1.1.1.4 christos #include "opcode/ft32.h"
31 1.1 christos
32 1.1.1.6 christos static bool debug_relax = false;
33 1.1.1.4 christos
34 1.1.1.4 christos static bfd_reloc_status_type
35 1.1.1.4 christos bfd_elf_ft32_diff_reloc (bfd *, arelent *, asymbol *, void *,
36 1.1.1.4 christos asection *, bfd *, char **);
37 1.1 christos
38 1.1 christos static reloc_howto_type ft32_elf_howto_table [] =
39 1.1 christos {
40 1.1 christos /* This reloc does nothing. */
41 1.1 christos HOWTO (R_FT32_NONE, /* type */
42 1.1 christos 0, /* rightshift */
43 1.1.1.6 christos 0, /* size */
44 1.1.1.6 christos 0, /* bitsize */
45 1.1.1.6 christos false, /* pc_relative */
46 1.1 christos 0, /* bitpos */
47 1.1.1.6 christos complain_overflow_dont, /* complain_on_overflow */
48 1.1 christos bfd_elf_generic_reloc, /* special_function */
49 1.1 christos "R_FT32_NONE", /* name */
50 1.1.1.6 christos false, /* partial_inplace */
51 1.1 christos 0, /* src_mask */
52 1.1 christos 0, /* dst_mask */
53 1.1.1.6 christos false), /* pcrel_offset */
54 1.1 christos
55 1.1 christos /* A 32 bit absolute relocation. */
56 1.1 christos
57 1.1 christos HOWTO (R_FT32_32, /* type */
58 1.1 christos 0, /* rightshift */
59 1.1.1.6 christos 4, /* size */
60 1.1 christos 32, /* bitsize */
61 1.1.1.6 christos false, /* pc_relative */
62 1.1 christos 0, /* bitpos */
63 1.1 christos complain_overflow_bitfield, /* complain_on_overflow */
64 1.1 christos bfd_elf_generic_reloc, /* special_function */
65 1.1 christos "R_FT32_32", /* name */
66 1.1.1.6 christos false, /* partial_inplace */
67 1.1 christos 0x00000000, /* src_mask */
68 1.1 christos 0xffffffff, /* dst_mask */
69 1.1.1.6 christos false), /* pcrel_offset */
70 1.1 christos
71 1.1 christos HOWTO (R_FT32_16, /* type */
72 1.1 christos 0, /* rightshift */
73 1.1.1.6 christos 2, /* size */
74 1.1 christos 16, /* bitsize */
75 1.1.1.6 christos false, /* pc_relative */
76 1.1 christos 0, /* bitpos */
77 1.1.1.4 christos complain_overflow_dont, /* complain_on_overflow */
78 1.1 christos bfd_elf_generic_reloc, /* special_function */
79 1.1 christos "R_FT32_16", /* name */
80 1.1.1.6 christos false, /* partial_inplace */
81 1.1 christos 0x00000000, /* src_mask */
82 1.1 christos 0x0000ffff, /* dst_mask */
83 1.1.1.6 christos false), /* pcrel_offset */
84 1.1 christos
85 1.1 christos HOWTO (R_FT32_8, /* type */
86 1.1 christos 0, /* rightshift */
87 1.1.1.6 christos 1, /* size */
88 1.1 christos 8, /* bitsize */
89 1.1.1.6 christos false, /* pc_relative */
90 1.1 christos 0, /* bitpos */
91 1.1 christos complain_overflow_signed, /* complain_on_overflow */
92 1.1 christos bfd_elf_generic_reloc, /* special_function */
93 1.1 christos "R_FT32_8", /* name */
94 1.1.1.6 christos false, /* partial_inplace */
95 1.1 christos 0x00000000, /* src_mask */
96 1.1 christos 0x000000ff, /* dst_mask */
97 1.1.1.6 christos false), /* pcrel_offset */
98 1.1 christos
99 1.1 christos HOWTO (R_FT32_10, /* type */
100 1.1 christos 0, /* rightshift */
101 1.1.1.6 christos 2, /* size */
102 1.1 christos 10, /* bitsize */
103 1.1.1.6 christos false, /* pc_relative */
104 1.1 christos 4, /* bitpos */
105 1.1.1.4 christos complain_overflow_bitfield, /* complain_on_overflow */
106 1.1 christos bfd_elf_generic_reloc, /* special_function */
107 1.1 christos "R_FT32_10", /* name */
108 1.1.1.6 christos false, /* partial_inplace */
109 1.1 christos 0x00000000, /* src_mask */
110 1.1 christos 0x00003ff0, /* dst_mask */
111 1.1.1.6 christos false), /* pcrel_offset */
112 1.1 christos
113 1.1 christos HOWTO (R_FT32_20, /* type */
114 1.1 christos 0, /* rightshift */
115 1.1.1.6 christos 4, /* size */
116 1.1 christos 20, /* bitsize */
117 1.1.1.6 christos false, /* pc_relative */
118 1.1 christos 0, /* bitpos */
119 1.1 christos complain_overflow_dont, /* complain_on_overflow */
120 1.1 christos bfd_elf_generic_reloc, /* special_function */
121 1.1 christos "R_FT32_20", /* name */
122 1.1.1.6 christos false, /* partial_inplace */
123 1.1 christos 0x00000000, /* src_mask */
124 1.1 christos 0x000fffff, /* dst_mask */
125 1.1.1.6 christos false), /* pcrel_offset */
126 1.1 christos
127 1.1 christos HOWTO (R_FT32_17, /* type */
128 1.1 christos 0, /* rightshift */
129 1.1.1.6 christos 4, /* size */
130 1.1 christos 17, /* bitsize */
131 1.1.1.6 christos false, /* pc_relative */
132 1.1 christos 0, /* bitpos */
133 1.1 christos complain_overflow_dont, /* complain_on_overflow */
134 1.1 christos bfd_elf_generic_reloc, /* special_function */
135 1.1 christos "R_FT32_17", /* name */
136 1.1.1.6 christos false, /* partial_inplace */
137 1.1 christos 0x00000000, /* src_mask */
138 1.1 christos 0x0001ffff, /* dst_mask */
139 1.1.1.6 christos false), /* pcrel_offset */
140 1.1 christos
141 1.1 christos HOWTO (R_FT32_18, /* type */
142 1.1 christos 2, /* rightshift */
143 1.1.1.6 christos 4, /* size */
144 1.1 christos 18, /* bitsize */
145 1.1.1.6 christos false, /* pc_relative */
146 1.1 christos 0, /* bitpos */
147 1.1.1.4 christos complain_overflow_dont, /* complain_on_overflow */
148 1.1 christos bfd_elf_generic_reloc, /* special_function */
149 1.1 christos "R_FT32_18", /* name */
150 1.1.1.6 christos false, /* partial_inplace */
151 1.1 christos 0x00000000, /* src_mask */
152 1.1 christos 0x0003ffff, /* dst_mask */
153 1.1.1.6 christos false), /* pcrel_offset */
154 1.1 christos
155 1.1.1.4 christos HOWTO (R_FT32_RELAX, /* type */
156 1.1.1.4 christos 0, /* rightshift */
157 1.1.1.6 christos 2, /* size */
158 1.1.1.4 christos 10, /* bitsize */
159 1.1.1.6 christos false, /* pc_relative */
160 1.1.1.4 christos 4, /* bitpos */
161 1.1.1.4 christos complain_overflow_signed, /* complain_on_overflow */
162 1.1.1.4 christos bfd_elf_generic_reloc, /* special_function */
163 1.1.1.4 christos "R_FT32_RELAX", /* name */
164 1.1.1.6 christos false, /* partial_inplace */
165 1.1.1.4 christos 0x00000000, /* src_mask */
166 1.1.1.4 christos 0x00000000, /* dst_mask */
167 1.1.1.6 christos false), /* pcrel_offset */
168 1.1.1.4 christos
169 1.1.1.4 christos HOWTO (R_FT32_SC0, /* type */
170 1.1.1.4 christos 0, /* rightshift */
171 1.1.1.6 christos 2, /* size */
172 1.1.1.4 christos 10, /* bitsize */
173 1.1.1.6 christos false, /* pc_relative */
174 1.1.1.4 christos 4, /* bitpos */
175 1.1.1.4 christos complain_overflow_signed, /* complain_on_overflow */
176 1.1.1.4 christos bfd_elf_generic_reloc, /* special_function */
177 1.1.1.4 christos "R_FT32_SC0", /* name */
178 1.1.1.6 christos false, /* partial_inplace */
179 1.1.1.4 christos 0x00000000, /* src_mask */
180 1.1.1.4 christos 0x00000000, /* dst_mask */
181 1.1.1.6 christos false), /* pcrel_offset */
182 1.1.1.4 christos HOWTO (R_FT32_SC1, /* type */
183 1.1.1.4 christos 2, /* rightshift */
184 1.1.1.6 christos 4, /* size */
185 1.1.1.4 christos 22, /* bitsize */
186 1.1.1.6 christos true, /* pc_relative */
187 1.1.1.4 christos 7, /* bitpos */
188 1.1.1.4 christos complain_overflow_dont, /* complain_on_overflow */
189 1.1.1.4 christos bfd_elf_generic_reloc, /* special_function */
190 1.1.1.4 christos "R_FT32_SC1", /* name */
191 1.1.1.6 christos true, /* partial_inplace */
192 1.1.1.4 christos 0x07ffff80, /* src_mask */
193 1.1.1.4 christos 0x07ffff80, /* dst_mask */
194 1.1.1.6 christos false), /* pcrel_offset */
195 1.1.1.4 christos HOWTO (R_FT32_15, /* type */
196 1.1.1.4 christos 0, /* rightshift */
197 1.1.1.6 christos 4, /* size */
198 1.1.1.4 christos 15, /* bitsize */
199 1.1.1.6 christos false, /* pc_relative */
200 1.1.1.4 christos 0, /* bitpos */
201 1.1.1.4 christos complain_overflow_dont, /* complain_on_overflow */
202 1.1.1.4 christos bfd_elf_generic_reloc, /* special_function */
203 1.1.1.4 christos "R_FT32_15", /* name */
204 1.1.1.6 christos false, /* partial_inplace */
205 1.1.1.4 christos 0x00000000, /* src_mask */
206 1.1.1.4 christos 0x00007fff, /* dst_mask */
207 1.1.1.6 christos false), /* pcrel_offset */
208 1.1.1.4 christos HOWTO (R_FT32_DIFF32, /* type */
209 1.1.1.4 christos 0, /* rightshift */
210 1.1.1.6 christos 4, /* size */
211 1.1.1.4 christos 32, /* bitsize */
212 1.1.1.6 christos false, /* pc_relative */
213 1.1.1.4 christos 0, /* bitpos */
214 1.1.1.4 christos complain_overflow_dont, /* complain_on_overflow */
215 1.1.1.4 christos bfd_elf_ft32_diff_reloc, /* special_function */
216 1.1.1.4 christos "R_FT32_DIFF32", /* name */
217 1.1.1.6 christos false, /* partial_inplace */
218 1.1.1.4 christos 0, /* src_mask */
219 1.1.1.4 christos 0xffffffff, /* dst_mask */
220 1.1.1.6 christos false), /* pcrel_offset */
221 1.1 christos };
222 1.1 christos
223 1.1 christos /* Map BFD reloc types to FT32 ELF reloc types. */
225 1.1 christos
226 1.1 christos struct ft32_reloc_map
227 1.1 christos {
228 1.1 christos bfd_reloc_code_real_type bfd_reloc_val;
229 1.1 christos unsigned int ft32_reloc_val;
230 1.1 christos };
231 1.1 christos
232 1.1 christos static const struct ft32_reloc_map ft32_reloc_map [] =
233 1.1.1.4 christos {
234 1.1.1.4 christos { BFD_RELOC_NONE, R_FT32_NONE },
235 1.1.1.4 christos { BFD_RELOC_32, R_FT32_32 },
236 1.1.1.4 christos { BFD_RELOC_16, R_FT32_16 },
237 1.1.1.4 christos { BFD_RELOC_8, R_FT32_8 },
238 1.1.1.4 christos { BFD_RELOC_FT32_10, R_FT32_10 },
239 1.1.1.4 christos { BFD_RELOC_FT32_20, R_FT32_20 },
240 1.1.1.4 christos { BFD_RELOC_FT32_17, R_FT32_17 },
241 1.1.1.4 christos { BFD_RELOC_FT32_18, R_FT32_18 },
242 1.1.1.4 christos { BFD_RELOC_FT32_RELAX, R_FT32_RELAX },
243 1.1.1.4 christos { BFD_RELOC_FT32_SC0, R_FT32_SC0 },
244 1.1.1.4 christos { BFD_RELOC_FT32_SC1, R_FT32_SC1 },
245 1.1.1.4 christos { BFD_RELOC_FT32_15, R_FT32_15 },
246 1.1 christos { BFD_RELOC_FT32_DIFF32, R_FT32_DIFF32 },
247 1.1 christos };
248 1.1.1.4 christos
249 1.1.1.4 christos /* Perform a diff relocation. Nothing to do, as the difference value is
250 1.1.1.4 christos already written into the section's contents. */
251 1.1.1.4 christos
252 1.1.1.4 christos static bfd_reloc_status_type
253 1.1.1.4 christos bfd_elf_ft32_diff_reloc (bfd *abfd ATTRIBUTE_UNUSED,
254 1.1.1.4 christos arelent *reloc_entry ATTRIBUTE_UNUSED,
255 1.1.1.4 christos asymbol *symbol ATTRIBUTE_UNUSED,
256 1.1.1.4 christos void *data ATTRIBUTE_UNUSED,
257 1.1.1.4 christos asection *input_section ATTRIBUTE_UNUSED,
258 1.1.1.4 christos bfd *output_bfd ATTRIBUTE_UNUSED,
259 1.1.1.4 christos char **error_message ATTRIBUTE_UNUSED)
260 1.1.1.4 christos {
261 1.1.1.4 christos return bfd_reloc_ok;
262 1.1.1.4 christos }
263 1.1 christos
264 1.1 christos static reloc_howto_type *
265 1.1 christos ft32_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
266 1.1 christos bfd_reloc_code_real_type code)
267 1.1 christos {
268 1.1 christos unsigned int i;
269 1.1.1.6 christos
270 1.1 christos for (i = 0; i < sizeof (ft32_reloc_map) / sizeof (ft32_reloc_map[0]); i++)
271 1.1 christos if (ft32_reloc_map [i].bfd_reloc_val == code)
272 1.1 christos return & ft32_elf_howto_table [ft32_reloc_map[i].ft32_reloc_val];
273 1.1 christos
274 1.1 christos return NULL;
275 1.1 christos }
276 1.1 christos
277 1.1 christos static reloc_howto_type *
278 1.1 christos ft32_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
279 1.1 christos {
280 1.1 christos unsigned int i;
281 1.1 christos
282 1.1 christos for (i = 0;
283 1.1 christos i < sizeof (ft32_elf_howto_table) / sizeof (ft32_elf_howto_table[0]);
284 1.1 christos i++)
285 1.1 christos if (ft32_elf_howto_table[i].name != NULL
286 1.1 christos && strcasecmp (ft32_elf_howto_table[i].name, r_name) == 0)
287 1.1 christos return &ft32_elf_howto_table[i];
288 1.1 christos
289 1.1 christos return NULL;
290 1.1 christos }
291 1.1 christos
292 1.1 christos /* Set the howto pointer for an FT32 ELF reloc. */
293 1.1.1.6 christos
294 1.1.1.4 christos static bool
295 1.1 christos ft32_info_to_howto_rela (bfd *abfd,
296 1.1 christos arelent *cache_ptr,
297 1.1 christos Elf_Internal_Rela *dst)
298 1.1 christos {
299 1.1 christos unsigned int r_type;
300 1.1 christos
301 1.1.1.4 christos r_type = ELF32_R_TYPE (dst->r_info);
302 1.1.1.4 christos if (r_type >= (unsigned int) R_FT32_max)
303 1.1.1.4 christos {
304 1.1.1.4 christos /* xgettext:c-format */
305 1.1.1.4 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
306 1.1.1.4 christos abfd, r_type);
307 1.1.1.6 christos bfd_set_error (bfd_error_bad_value);
308 1.1.1.4 christos return false;
309 1.1.1.4 christos }
310 1.1 christos
311 1.1.1.4 christos cache_ptr->howto = & ft32_elf_howto_table [r_type];
312 1.1 christos return cache_ptr->howto != NULL;
313 1.1.1.4 christos }
314 1.1 christos
315 1.1 christos /* Relocate an FT32 ELF section.
316 1.1 christos
317 1.1 christos The RELOCATE_SECTION function is called by the new ELF backend linker
318 1.1 christos to handle the relocations for a section.
319 1.1 christos
320 1.1 christos The relocs are always passed as Rela structures; if the section
321 1.1 christos actually uses Rel structures, the r_addend field will always be
322 1.1 christos zero.
323 1.1 christos
324 1.1 christos This function is responsible for adjusting the section contents as
325 1.1 christos necessary, and (if using Rela relocs and generating a relocatable
326 1.1 christos output file) adjusting the reloc addend as necessary.
327 1.1 christos
328 1.1 christos This function does not have to worry about setting the reloc
329 1.1 christos address or the reloc symbol index.
330 1.1 christos
331 1.1 christos LOCAL_SYMS is a pointer to the swapped in local symbols.
332 1.1 christos
333 1.1 christos LOCAL_SECTIONS is an array giving the section in the input file
334 1.1 christos corresponding to the st_shndx field of each local symbol.
335 1.1 christos
336 1.1 christos The global hash table entry for the global symbols can be found
337 1.1 christos via elf_sym_hashes (input_bfd).
338 1.1 christos
339 1.1 christos When generating relocatable output, this function must handle
340 1.1 christos STB_LOCAL/STT_SECTION symbols specially. The output symbol is
341 1.1 christos going to be the section symbol corresponding to the output
342 1.1 christos section, which means that the addend must be adjusted
343 1.1 christos accordingly. */
344 1.1.1.6 christos
345 1.1 christos static int
346 1.1 christos ft32_elf_relocate_section (bfd *output_bfd,
347 1.1 christos struct bfd_link_info *info,
348 1.1 christos bfd *input_bfd,
349 1.1 christos asection *input_section,
350 1.1 christos bfd_byte *contents,
351 1.1 christos Elf_Internal_Rela *relocs,
352 1.1 christos Elf_Internal_Sym *local_syms,
353 1.1 christos asection **local_sections)
354 1.1 christos {
355 1.1 christos Elf_Internal_Shdr *symtab_hdr;
356 1.1 christos struct elf_link_hash_entry **sym_hashes;
357 1.1 christos Elf_Internal_Rela *rel;
358 1.1 christos Elf_Internal_Rela *relend;
359 1.1 christos
360 1.1 christos symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
361 1.1 christos sym_hashes = elf_sym_hashes (input_bfd);
362 1.1 christos relend = relocs + input_section->reloc_count;
363 1.1 christos
364 1.1 christos for (rel = relocs; rel < relend; rel ++)
365 1.1 christos {
366 1.1 christos reloc_howto_type *howto;
367 1.1 christos unsigned long r_symndx;
368 1.1 christos Elf_Internal_Sym *sym;
369 1.1 christos asection *sec;
370 1.1 christos struct elf_link_hash_entry *h;
371 1.1 christos bfd_vma relocation;
372 1.1 christos bfd_reloc_status_type r;
373 1.1 christos const char *name;
374 1.1 christos int r_type;
375 1.1 christos
376 1.1 christos r_type = ELF32_R_TYPE (rel->r_info);
377 1.1 christos r_symndx = ELF32_R_SYM (rel->r_info);
378 1.1 christos howto = ft32_elf_howto_table + r_type;
379 1.1 christos h = NULL;
380 1.1 christos sym = NULL;
381 1.1 christos sec = NULL;
382 1.1 christos
383 1.1 christos if (r_symndx < symtab_hdr->sh_info)
384 1.1 christos {
385 1.1 christos sym = local_syms + r_symndx;
386 1.1 christos sec = local_sections [r_symndx];
387 1.1 christos relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
388 1.1 christos
389 1.1 christos name = bfd_elf_string_from_elf_section
390 1.1.1.5 christos (input_bfd, symtab_hdr->sh_link, sym->st_name);
391 1.1 christos name = name == NULL ? bfd_section_name (sec) : name;
392 1.1 christos }
393 1.1 christos else
394 1.1.1.6 christos {
395 1.1 christos bool unresolved_reloc, warned, ignored;
396 1.1 christos
397 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
398 1.1 christos r_symndx, symtab_hdr, sym_hashes,
399 1.1 christos h, sec, relocation,
400 1.1 christos unresolved_reloc, warned, ignored);
401 1.1 christos
402 1.1 christos name = h->root.root.string;
403 1.1 christos }
404 1.1 christos
405 1.1 christos if (sec != NULL && discarded_section (sec))
406 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
407 1.1 christos rel, 1, relend, howto, 0, contents);
408 1.1.1.2 christos
409 1.1 christos if (bfd_link_relocatable (info))
410 1.1 christos continue;
411 1.1.1.4 christos
412 1.1.1.4 christos switch (howto->type)
413 1.1.1.4 christos {
414 1.1.1.4 christos case R_FT32_SC0:
415 1.1.1.4 christos {
416 1.1.1.4 christos unsigned int insn;
417 1.1.1.4 christos int offset;
418 1.1.1.4 christos unsigned int code15[2];
419 1.1.1.4 christos
420 1.1.1.4 christos insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
421 1.1.1.4 christos ft32_split_shortcode (insn, code15);
422 1.1.1.4 christos
423 1.1.1.4 christos offset = (int)relocation;
424 1.1.1.4 christos offset += (int)(rel->r_addend - rel->r_offset);
425 1.1.1.4 christos offset -= (input_section->output_section->vma +
426 1.1.1.4 christos input_section->output_offset);
427 1.1.1.4 christos if ((offset < -1024) || (offset >= 1024))
428 1.1.1.4 christos {
429 1.1.1.4 christos r = bfd_reloc_outofrange;
430 1.1.1.4 christos break;
431 1.1.1.4 christos }
432 1.1.1.4 christos code15[0] |= ((offset / 4) & 511);
433 1.1.1.4 christos insn = ft32_merge_shortcode (code15);
434 1.1.1.4 christos bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
435 1.1.1.4 christos }
436 1.1.1.4 christos r = bfd_reloc_ok;
437 1.1.1.4 christos break;
438 1.1.1.4 christos
439 1.1.1.4 christos case R_FT32_SC1:
440 1.1.1.4 christos {
441 1.1.1.4 christos unsigned int insn;
442 1.1.1.4 christos int offset;
443 1.1.1.4 christos unsigned int code15[2];
444 1.1.1.4 christos
445 1.1.1.4 christos insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
446 1.1.1.4 christos ft32_split_shortcode (insn, code15);
447 1.1.1.4 christos
448 1.1.1.4 christos offset = (int)relocation;
449 1.1.1.4 christos offset += (int)(rel->r_addend - rel->r_offset);
450 1.1.1.4 christos offset -= (input_section->output_section->vma +
451 1.1.1.4 christos input_section->output_offset);
452 1.1.1.4 christos if ((offset < -1024) || (offset >= 1024))
453 1.1.1.4 christos {
454 1.1.1.4 christos r = bfd_reloc_outofrange;
455 1.1.1.4 christos break;
456 1.1.1.4 christos }
457 1.1.1.4 christos code15[1] |= ((offset / 4) & 511);
458 1.1.1.4 christos insn = ft32_merge_shortcode (code15);
459 1.1.1.4 christos bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
460 1.1.1.4 christos }
461 1.1.1.4 christos r = bfd_reloc_ok;
462 1.1.1.4 christos break;
463 1.1.1.4 christos
464 1.1.1.4 christos case R_FT32_DIFF32:
465 1.1.1.4 christos r = bfd_reloc_ok;
466 1.1.1.4 christos break;
467 1.1.1.4 christos
468 1.1.1.4 christos default:
469 1.1.1.4 christos r = _bfd_final_link_relocate (howto, input_bfd, input_section,
470 1.1.1.4 christos contents, rel->r_offset,
471 1.1.1.4 christos relocation, rel->r_addend);
472 1.1.1.4 christos break;
473 1.1 christos }
474 1.1 christos
475 1.1 christos if (r != bfd_reloc_ok)
476 1.1 christos {
477 1.1 christos const char * msg = NULL;
478 1.1 christos
479 1.1 christos switch (r)
480 1.1 christos {
481 1.1.1.2 christos case bfd_reloc_overflow:
482 1.1 christos (*info->callbacks->reloc_overflow)
483 1.1 christos (info, (h ? &h->root : NULL), name, howto->name,
484 1.1 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
485 1.1 christos break;
486 1.1 christos
487 1.1.1.2 christos case bfd_reloc_undefined:
488 1.1.1.6 christos (*info->callbacks->undefined_symbol)
489 1.1 christos (info, name, input_bfd, input_section, rel->r_offset, true);
490 1.1 christos break;
491 1.1 christos
492 1.1 christos case bfd_reloc_outofrange:
493 1.1 christos msg = _("internal error: out of range error");
494 1.1 christos break;
495 1.1 christos
496 1.1 christos case bfd_reloc_notsupported:
497 1.1 christos msg = _("internal error: unsupported relocation error");
498 1.1 christos break;
499 1.1 christos
500 1.1 christos case bfd_reloc_dangerous:
501 1.1 christos msg = _("internal error: dangerous relocation");
502 1.1 christos break;
503 1.1 christos
504 1.1 christos default:
505 1.1 christos msg = _("internal error: unknown error");
506 1.1 christos break;
507 1.1 christos }
508 1.1 christos
509 1.1.1.2 christos if (msg)
510 1.1.1.2 christos (*info->callbacks->warning) (info, msg, name, input_bfd,
511 1.1 christos input_section, rel->r_offset);
512 1.1 christos }
513 1.1 christos }
514 1.1.1.6 christos
515 1.1 christos return true;
516 1.1 christos }
517 1.1.1.4 christos
518 1.1.1.4 christos /* Relaxation. */
520 1.1.1.4 christos
521 1.1.1.4 christos static bool
522 1.1.1.4 christos ft32_reloc_shortable
523 1.1.1.4 christos (bfd * abfd,
524 1.1.1.4 christos asection * sec,
525 1.1.1.4 christos Elf_Internal_Sym * isymbuf ATTRIBUTE_UNUSED,
526 1.1.1.4 christos bfd_byte * contents,
527 1.1.1.4 christos bfd_vma pc ATTRIBUTE_UNUSED,
528 1.1.1.4 christos Elf_Internal_Rela * irel,
529 1.1.1.4 christos unsigned int * sc)
530 1.1.1.4 christos {
531 1.1.1.4 christos Elf_Internal_Shdr *symtab_hdr ATTRIBUTE_UNUSED;
532 1.1.1.4 christos bfd_vma symval;
533 1.1.1.4 christos
534 1.1.1.4 christos enum elf_ft32_reloc_type r_type;
535 1.1.1.4 christos reloc_howto_type *howto = NULL;
536 1.1.1.4 christos unsigned int insn;
537 1.1.1.4 christos int offset;
538 1.1.1.4 christos bfd_vma dot, value;
539 1.1.1.4 christos
540 1.1.1.4 christos r_type = ELF32_R_TYPE (irel->r_info);
541 1.1.1.4 christos howto = &ft32_elf_howto_table [r_type];
542 1.1.1.4 christos
543 1.1.1.4 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
544 1.1.1.4 christos
545 1.1.1.4 christos /* Get the value of the symbol referred to by the reloc. */
546 1.1.1.4 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
547 1.1.1.4 christos {
548 1.1.1.4 christos /* A local symbol. */
549 1.1.1.4 christos Elf_Internal_Sym *isym;
550 1.1.1.4 christos asection *sym_sec;
551 1.1.1.4 christos
552 1.1.1.4 christos isym = isymbuf + ELF32_R_SYM (irel->r_info);
553 1.1.1.4 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
554 1.1.1.4 christos symval = isym->st_value;
555 1.1.1.4 christos /* If the reloc is absolute, it will not have
556 1.1.1.4 christos a symbol or section associated with it. */
557 1.1.1.4 christos if (sym_sec)
558 1.1.1.4 christos symval += sym_sec->output_section->vma
559 1.1.1.4 christos + sym_sec->output_offset;
560 1.1.1.4 christos }
561 1.1.1.4 christos else
562 1.1.1.4 christos {
563 1.1.1.4 christos unsigned long indx;
564 1.1.1.4 christos struct elf_link_hash_entry *h;
565 1.1.1.4 christos
566 1.1.1.4 christos /* An external symbol. */
567 1.1.1.4 christos indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
568 1.1.1.4 christos h = elf_sym_hashes (abfd)[indx];
569 1.1.1.4 christos BFD_ASSERT (h != NULL);
570 1.1.1.4 christos if (h->root.type != bfd_link_hash_defined
571 1.1.1.4 christos && h->root.type != bfd_link_hash_defweak)
572 1.1.1.4 christos /* This appears to be a reference to an undefined
573 1.1.1.6 christos symbol. Just ignore it--it will be caught by the
574 1.1.1.4 christos regular reloc processing. */
575 1.1.1.4 christos return false;
576 1.1.1.4 christos
577 1.1.1.4 christos symval = (h->root.u.def.value
578 1.1.1.4 christos + h->root.u.def.section->output_section->vma
579 1.1.1.4 christos + h->root.u.def.section->output_offset);
580 1.1.1.4 christos }
581 1.1.1.4 christos
582 1.1.1.4 christos switch (r_type)
583 1.1.1.4 christos {
584 1.1.1.4 christos case R_FT32_8:
585 1.1.1.4 christos case R_FT32_10:
586 1.1.1.4 christos case R_FT32_16:
587 1.1.1.4 christos case R_FT32_20:
588 1.1.1.6 christos case R_FT32_RELAX:
589 1.1.1.4 christos if (symval != 0)
590 1.1.1.4 christos return false;
591 1.1.1.4 christos insn = bfd_get_32 (abfd, contents + irel->r_offset);
592 1.1.1.4 christos insn |= ((symval + irel->r_addend) << howto->bitpos) & howto->dst_mask;
593 1.1.1.4 christos return ft32_shortcode (insn, sc);
594 1.1.1.4 christos
595 1.1.1.4 christos case R_FT32_18:
596 1.1.1.4 christos insn = bfd_get_32 (abfd, contents + irel->r_offset);
597 1.1.1.4 christos /* Get the address of this instruction. */
598 1.1.1.4 christos dot = (sec->output_section->vma
599 1.1.1.4 christos + sec->output_offset + irel->r_offset);
600 1.1.1.4 christos value = symval + irel->r_addend;
601 1.1.1.4 christos offset = (value - dot) / 4;
602 1.1.1.4 christos
603 1.1.1.4 christos if ((dot > 0x8c) && (-256 <= offset) && (offset < 256))
604 1.1.1.4 christos {
605 1.1.1.6 christos switch (insn)
606 1.1.1.6 christos {
607 1.1.1.6 christos case 0x00200000: *sc = (3 << 13) | (0 << 9); return true;
608 1.1.1.6 christos case 0x00280000: *sc = (3 << 13) | (1 << 9); return true;
609 1.1.1.6 christos case 0x00600000: *sc = (3 << 13) | (2 << 9); return true;
610 1.1.1.6 christos case 0x00680000: *sc = (3 << 13) | (3 << 9); return true;
611 1.1.1.6 christos case 0x00a00000: *sc = (3 << 13) | (4 << 9); return true;
612 1.1.1.6 christos case 0x00a80000: *sc = (3 << 13) | (5 << 9); return true;
613 1.1.1.6 christos case 0x00e00000: *sc = (3 << 13) | (6 << 9); return true;
614 1.1.1.6 christos case 0x00e80000: *sc = (3 << 13) | (7 << 9); return true;
615 1.1.1.6 christos case 0x01200000: *sc = (3 << 13) | (8 << 9); return true;
616 1.1.1.6 christos case 0x01280000: *sc = (3 << 13) | (9 << 9); return true;
617 1.1.1.6 christos case 0x01600000: *sc = (3 << 13) | (10 << 9); return true;
618 1.1.1.6 christos case 0x01680000: *sc = (3 << 13) | (11 << 9); return true;
619 1.1.1.4 christos case 0x01a00000: *sc = (3 << 13) | (12 << 9); return true;
620 1.1.1.6 christos case 0x01a80000: *sc = (3 << 13) | (13 << 9); return true;
621 1.1.1.6 christos
622 1.1.1.4 christos case 0x00300000: *sc = (3 << 13) | (14 << 9); return true;
623 1.1.1.4 christos case 0x00340000: *sc = (3 << 13) | (15 << 9); return true;
624 1.1.1.4 christos
625 1.1.1.4 christos default:
626 1.1.1.4 christos break;
627 1.1.1.4 christos }
628 1.1.1.4 christos }
629 1.1.1.4 christos break;
630 1.1.1.4 christos
631 1.1.1.4 christos default:
632 1.1.1.6 christos break;
633 1.1.1.4 christos }
634 1.1.1.4 christos return false;
635 1.1.1.4 christos }
636 1.1.1.4 christos
637 1.1.1.6 christos /* Returns whether the relocation type passed is a diff reloc. */
638 1.1.1.4 christos
639 1.1.1.4 christos static bool
640 1.1.1.4 christos elf32_ft32_is_diff_reloc (Elf_Internal_Rela *irel)
641 1.1.1.4 christos {
642 1.1.1.4 christos return (ELF32_R_TYPE (irel->r_info) == R_FT32_DIFF32);
643 1.1.1.4 christos }
644 1.1.1.4 christos
645 1.1.1.4 christos /* Reduce the diff value written in the section by count if the shrinked
646 1.1.1.4 christos insn address happens to fall between the two symbols for which this
647 1.1.1.6 christos diff reloc was emitted. */
648 1.1.1.4 christos
649 1.1.1.4 christos static bool
650 1.1.1.4 christos elf32_ft32_adjust_diff_reloc_value (bfd *abfd,
651 1.1.1.4 christos struct bfd_section *isec,
652 1.1.1.4 christos Elf_Internal_Rela *irel,
653 1.1.1.4 christos bfd_vma symval,
654 1.1.1.4 christos bfd_vma shrinked_insn_address,
655 1.1.1.4 christos int count)
656 1.1.1.4 christos {
657 1.1.1.4 christos unsigned char * reloc_contents = NULL;
658 1.1.1.4 christos unsigned char * isec_contents = elf_section_data (isec)->this_hdr.contents;
659 1.1.1.4 christos bfd_signed_vma x = 0;
660 1.1.1.4 christos bfd_vma sym2_address;
661 1.1.1.4 christos bfd_vma sym1_address;
662 1.1.1.4 christos bfd_vma start_address;
663 1.1.1.4 christos bfd_vma end_address;
664 1.1.1.4 christos
665 1.1.1.4 christos
666 1.1.1.4 christos if (isec_contents == NULL)
667 1.1.1.6 christos {
668 1.1.1.4 christos if (! bfd_malloc_and_get_section (abfd, isec, &isec_contents))
669 1.1.1.4 christos return false;
670 1.1.1.4 christos
671 1.1.1.4 christos elf_section_data (isec)->this_hdr.contents = isec_contents;
672 1.1.1.4 christos }
673 1.1.1.4 christos
674 1.1.1.4 christos reloc_contents = isec_contents + irel->r_offset;
675 1.1.1.4 christos
676 1.1.1.4 christos /* Read value written in object file. */
677 1.1.1.4 christos switch (ELF32_R_TYPE (irel->r_info))
678 1.1.1.4 christos {
679 1.1.1.4 christos case R_FT32_DIFF32:
680 1.1.1.4 christos x = bfd_get_signed_32 (abfd, reloc_contents);
681 1.1.1.4 christos break;
682 1.1.1.6 christos
683 1.1.1.4 christos default:
684 1.1.1.4 christos return false;
685 1.1.1.4 christos }
686 1.1.1.4 christos
687 1.1.1.4 christos /* For a diff reloc sym1 - sym2 the diff at assembly time (x) is written
688 1.1.1.4 christos into the object file at the reloc offset. sym2's logical value is
689 1.1.1.4 christos symval (<start_of_section>) + reloc addend. Compute the start and end
690 1.1.1.4 christos addresses and check if the shrinked insn falls between sym1 and sym2. */
691 1.1.1.4 christos sym2_address = symval + irel->r_addend;
692 1.1.1.4 christos sym1_address = sym2_address - x;
693 1.1.1.4 christos
694 1.1.1.4 christos /* Don't assume sym2 is bigger than sym1 - the difference
695 1.1.1.4 christos could be negative. Compute start and end addresses, and
696 1.1.1.4 christos use those to see if they span shrinked_insn_address. */
697 1.1.1.4 christos start_address = sym1_address < sym2_address ? sym1_address : sym2_address;
698 1.1.1.4 christos end_address = sym1_address > sym2_address ? sym1_address : sym2_address;
699 1.1.1.4 christos
700 1.1.1.4 christos if (shrinked_insn_address >= start_address
701 1.1.1.4 christos && shrinked_insn_address < end_address)
702 1.1.1.4 christos {
703 1.1.1.4 christos /* Reduce the diff value by count bytes and write it back into section
704 1.1.1.4 christos contents. */
705 1.1.1.4 christos bfd_signed_vma new_diff = x < 0 ? x + count : x - count;
706 1.1.1.4 christos
707 1.1.1.4 christos if (sym2_address > shrinked_insn_address)
708 1.1.1.4 christos irel->r_addend -= count;
709 1.1.1.4 christos
710 1.1.1.4 christos switch (ELF32_R_TYPE (irel->r_info))
711 1.1.1.4 christos {
712 1.1.1.4 christos case R_FT32_DIFF32:
713 1.1.1.4 christos bfd_put_signed_32 (abfd, new_diff & 0xFFFFFFFF, reloc_contents);
714 1.1.1.4 christos break;
715 1.1.1.6 christos
716 1.1.1.4 christos default:
717 1.1.1.4 christos return false;
718 1.1.1.4 christos }
719 1.1.1.6 christos }
720 1.1.1.4 christos
721 1.1.1.4 christos return true;
722 1.1.1.6 christos }
723 1.1.1.4 christos
724 1.1.1.4 christos static bool
725 1.1.1.4 christos elf32_ft32_adjust_reloc_if_spans_insn (bfd *abfd,
726 1.1.1.4 christos asection *isec,
727 1.1.1.4 christos Elf_Internal_Rela *irel, bfd_vma symval,
728 1.1.1.4 christos bfd_vma shrinked_insn_address,
729 1.1.1.4 christos bfd_vma shrink_boundary,
730 1.1.1.4 christos int count)
731 1.1.1.4 christos {
732 1.1.1.4 christos
733 1.1.1.4 christos if (elf32_ft32_is_diff_reloc (irel))
734 1.1.1.4 christos {
735 1.1.1.4 christos if (!elf32_ft32_adjust_diff_reloc_value (abfd, isec, irel,
736 1.1.1.4 christos symval,
737 1.1.1.6 christos shrinked_insn_address,
738 1.1.1.4 christos count))
739 1.1.1.4 christos return false;
740 1.1.1.4 christos }
741 1.1.1.4 christos else
742 1.1.1.6 christos {
743 1.1.1.4 christos bfd_vma reloc_value = symval + irel->r_addend;
744 1.1.1.6 christos bool addend_within_shrink_boundary =
745 1.1.1.4 christos (reloc_value <= shrink_boundary);
746 1.1.1.4 christos bool reloc_spans_insn =
747 1.1.1.4 christos (symval <= shrinked_insn_address
748 1.1.1.4 christos && reloc_value > shrinked_insn_address
749 1.1.1.4 christos && addend_within_shrink_boundary);
750 1.1.1.6 christos
751 1.1.1.4 christos if (! reloc_spans_insn)
752 1.1.1.4 christos return true;
753 1.1.1.4 christos
754 1.1.1.4 christos irel->r_addend -= count;
755 1.1.1.4 christos
756 1.1.1.4 christos if (debug_relax)
757 1.1.1.6 christos printf ("Relocation's addend needed to be fixed \n");
758 1.1.1.4 christos }
759 1.1.1.4 christos return true;
760 1.1.1.4 christos }
761 1.1.1.4 christos
762 1.1.1.6 christos /* Delete some bytes from a section while relaxing. */
763 1.1.1.4 christos
764 1.1.1.4 christos static bool
765 1.1.1.4 christos elf32_ft32_relax_delete_bytes (struct bfd_link_info *link_info, bfd * abfd,
766 1.1.1.4 christos asection * sec, bfd_vma addr, int count)
767 1.1.1.4 christos {
768 1.1.1.4 christos Elf_Internal_Shdr *symtab_hdr;
769 1.1.1.4 christos unsigned int sec_shndx;
770 1.1.1.4 christos bfd_byte *contents;
771 1.1.1.4 christos Elf_Internal_Rela *irel, *irelend;
772 1.1.1.4 christos bfd_vma toaddr;
773 1.1.1.4 christos Elf_Internal_Sym *isym;
774 1.1.1.4 christos Elf_Internal_Sym *isymend;
775 1.1.1.4 christos struct elf_link_hash_entry **sym_hashes;
776 1.1.1.4 christos struct elf_link_hash_entry **end_hashes;
777 1.1.1.4 christos struct elf_link_hash_entry **start_hashes;
778 1.1.1.4 christos unsigned int symcount;
779 1.1.1.4 christos Elf_Internal_Sym *isymbuf = NULL;
780 1.1.1.4 christos
781 1.1.1.4 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
782 1.1.1.4 christos sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
783 1.1.1.4 christos
784 1.1.1.4 christos contents = elf_section_data (sec)->this_hdr.contents;
785 1.1.1.4 christos
786 1.1.1.4 christos toaddr = sec->size;
787 1.1.1.4 christos
788 1.1.1.4 christos irel = elf_section_data (sec)->relocs;
789 1.1.1.4 christos irelend = irel + sec->reloc_count;
790 1.1.1.4 christos
791 1.1.1.4 christos /* Actually delete the bytes. */
792 1.1.1.4 christos memmove (contents + addr, contents + addr + count,
793 1.1.1.4 christos (size_t) (toaddr - addr - count));
794 1.1.1.4 christos sec->size -= count;
795 1.1.1.4 christos
796 1.1.1.4 christos /* Adjust all the relocs. */
797 1.1.1.4 christos for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
798 1.1.1.4 christos /* Get the new reloc address. */
799 1.1.1.4 christos if ((irel->r_offset > addr && irel->r_offset < toaddr))
800 1.1.1.4 christos irel->r_offset -= count;
801 1.1.1.4 christos
802 1.1.1.4 christos /* The reloc's own addresses are now ok. However, we need to readjust
803 1.1.1.4 christos the reloc's addend, i.e. the reloc's value if two conditions are met:
804 1.1.1.4 christos 1.) the reloc is relative to a symbol in this section that
805 1.1.1.4 christos is located in front of the shrinked instruction
806 1.1.1.4 christos 2.) symbol plus addend end up behind the shrinked instruction.
807 1.1.1.4 christos
808 1.1.1.4 christos The most common case where this happens are relocs relative to
809 1.1.1.4 christos the section-start symbol.
810 1.1.1.4 christos
811 1.1.1.4 christos This step needs to be done for all of the sections of the bfd. */
812 1.1.1.4 christos {
813 1.1.1.4 christos struct bfd_section *isec;
814 1.1.1.4 christos
815 1.1.1.4 christos for (isec = abfd->sections; isec; isec = isec->next)
816 1.1.1.4 christos {
817 1.1.1.4 christos bfd_vma symval;
818 1.1.1.4 christos bfd_vma shrinked_insn_address;
819 1.1.1.4 christos
820 1.1.1.4 christos if (isec->reloc_count == 0)
821 1.1.1.4 christos continue;
822 1.1.1.4 christos
823 1.1.1.4 christos shrinked_insn_address = (sec->output_section->vma
824 1.1.1.4 christos + sec->output_offset + addr - count);
825 1.1.1.4 christos
826 1.1.1.4 christos irel = elf_section_data (isec)->relocs;
827 1.1.1.6 christos /* PR 12161: Read in the relocs for this section if necessary. */
828 1.1.1.4 christos if (irel == NULL)
829 1.1.1.4 christos irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, true);
830 1.1.1.4 christos
831 1.1.1.4 christos for (irelend = irel + isec->reloc_count; irel < irelend; irel++)
832 1.1.1.4 christos {
833 1.1.1.4 christos /* Read this BFD's local symbols if we haven't done
834 1.1.1.4 christos so already. */
835 1.1.1.4 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0)
836 1.1.1.4 christos {
837 1.1.1.4 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
838 1.1.1.4 christos if (isymbuf == NULL)
839 1.1.1.4 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
840 1.1.1.4 christos symtab_hdr->sh_info, 0,
841 1.1.1.6 christos NULL, NULL, NULL);
842 1.1.1.4 christos if (isymbuf == NULL)
843 1.1.1.4 christos return false;
844 1.1.1.4 christos }
845 1.1.1.4 christos
846 1.1.1.4 christos /* Get the value of the symbol referred to by the reloc. */
847 1.1.1.4 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
848 1.1.1.4 christos {
849 1.1.1.4 christos /* A local symbol. */
850 1.1.1.4 christos asection *sym_sec;
851 1.1.1.4 christos
852 1.1.1.4 christos isym = isymbuf + ELF32_R_SYM (irel->r_info);
853 1.1.1.4 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
854 1.1.1.4 christos symval = isym->st_value;
855 1.1.1.4 christos /* If the reloc is absolute, it will not have
856 1.1.1.4 christos a symbol or section associated with it. */
857 1.1.1.4 christos if (sym_sec == sec)
858 1.1.1.4 christos {
859 1.1.1.4 christos symval += sym_sec->output_section->vma
860 1.1.1.4 christos + sym_sec->output_offset;
861 1.1.1.4 christos
862 1.1.1.4 christos if (debug_relax)
863 1.1.1.4 christos printf ("Checking if the relocation's "
864 1.1.1.4 christos "addend needs corrections.\n"
865 1.1.1.4 christos "Address of anchor symbol: 0x%x \n"
866 1.1.1.4 christos "Address of relocation target: 0x%x \n"
867 1.1.1.4 christos "Address of relaxed insn: 0x%x \n",
868 1.1.1.4 christos (unsigned int) symval,
869 1.1.1.4 christos (unsigned int) (symval + irel->r_addend),
870 1.1.1.4 christos (unsigned int) shrinked_insn_address);
871 1.1.1.4 christos
872 1.1.1.4 christos if (symval <= shrinked_insn_address
873 1.1.1.4 christos && (symval + irel->r_addend) > shrinked_insn_address)
874 1.1.1.4 christos {
875 1.1.1.4 christos /* If there is an alignment boundary, we only need to
876 1.1.1.4 christos adjust addends that end up below the boundary. */
877 1.1.1.4 christos bfd_vma shrink_boundary = (toaddr
878 1.1.1.4 christos + sec->output_section->vma
879 1.1.1.4 christos + sec->output_offset);
880 1.1.1.4 christos
881 1.1.1.4 christos if (debug_relax)
882 1.1.1.4 christos printf
883 1.1.1.4 christos ("Relocation's addend needed to be fixed \n");
884 1.1.1.4 christos
885 1.1.1.4 christos if (!elf32_ft32_adjust_reloc_if_spans_insn (abfd, isec,
886 1.1.1.4 christos irel, symval,
887 1.1.1.4 christos shrinked_insn_address,
888 1.1.1.6 christos shrink_boundary,
889 1.1.1.4 christos count))
890 1.1.1.4 christos return false;
891 1.1.1.4 christos }
892 1.1.1.4 christos }
893 1.1.1.4 christos /* else reference symbol is absolute. No adjustment needed. */
894 1.1.1.4 christos }
895 1.1.1.4 christos /* else...Reference symbol is extern. No need for adjusting
896 1.1.1.4 christos the addend. */
897 1.1.1.4 christos }
898 1.1.1.4 christos }
899 1.1.1.4 christos }
900 1.1.1.4 christos
901 1.1.1.4 christos /* Adjust the local symbols defined in this section. */
902 1.1.1.4 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
903 1.1.1.4 christos isym = (Elf_Internal_Sym *) symtab_hdr->contents;
904 1.1.1.4 christos if (isym)
905 1.1.1.4 christos {
906 1.1.1.4 christos for (isymend = isym + symtab_hdr->sh_info; isym < isymend; isym++)
907 1.1.1.4 christos {
908 1.1.1.4 christos if (isym->st_shndx == sec_shndx
909 1.1.1.4 christos && isym->st_value > addr && isym->st_value < toaddr)
910 1.1.1.4 christos isym->st_value -= count;
911 1.1.1.4 christos }
912 1.1.1.4 christos }
913 1.1.1.4 christos
914 1.1.1.4 christos /* Now adjust the global symbols defined in this section. */
915 1.1.1.4 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
916 1.1.1.4 christos - symtab_hdr->sh_info);
917 1.1.1.4 christos sym_hashes = start_hashes = elf_sym_hashes (abfd);
918 1.1.1.4 christos end_hashes = sym_hashes + symcount;
919 1.1.1.4 christos
920 1.1.1.4 christos for (; sym_hashes < end_hashes; sym_hashes++)
921 1.1.1.4 christos {
922 1.1.1.4 christos struct elf_link_hash_entry *sym_hash = *sym_hashes;
923 1.1.1.4 christos
924 1.1.1.4 christos /* The '--wrap SYMBOL' option is causing a pain when the object file,
925 1.1.1.4 christos containing the definition of __wrap_SYMBOL, includes a direct
926 1.1.1.4 christos call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
927 1.1.1.4 christos the same symbol (which is __wrap_SYMBOL), but still exist as two
928 1.1.1.4 christos different symbols in 'sym_hashes', we don't want to adjust
929 1.1.1.4 christos the global symbol __wrap_SYMBOL twice.
930 1.1.1.4 christos This check is only relevant when symbols are being wrapped. */
931 1.1.1.4 christos if (link_info->wrap_hash != NULL)
932 1.1.1.4 christos {
933 1.1.1.4 christos struct elf_link_hash_entry **cur_sym_hashes;
934 1.1.1.4 christos
935 1.1.1.4 christos /* Loop only over the symbols whom been already checked. */
936 1.1.1.4 christos for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
937 1.1.1.4 christos cur_sym_hashes++)
938 1.1.1.4 christos /* If the current symbol is identical to 'sym_hash', that means
939 1.1.1.4 christos the symbol was already adjusted (or at least checked). */
940 1.1.1.4 christos if (*cur_sym_hashes == sym_hash)
941 1.1.1.4 christos break;
942 1.1.1.4 christos
943 1.1.1.4 christos /* Don't adjust the symbol again. */
944 1.1.1.4 christos if (cur_sym_hashes < sym_hashes)
945 1.1.1.4 christos continue;
946 1.1.1.4 christos }
947 1.1.1.4 christos
948 1.1.1.4 christos if ((sym_hash->root.type == bfd_link_hash_defined
949 1.1.1.4 christos || sym_hash->root.type == bfd_link_hash_defweak)
950 1.1.1.4 christos && sym_hash->root.u.def.section == sec
951 1.1.1.4 christos && sym_hash->root.u.def.value > addr
952 1.1.1.4 christos && sym_hash->root.u.def.value < toaddr)
953 1.1.1.4 christos sym_hash->root.u.def.value -= count;
954 1.1.1.6 christos }
955 1.1.1.4 christos
956 1.1.1.4 christos return true;
957 1.1.1.4 christos }
958 1.1.1.4 christos
959 1.1.1.6 christos /* Return TRUE if LOC can be a target of a branch, jump or call. */
960 1.1.1.4 christos
961 1.1.1.4 christos static bool
962 1.1.1.4 christos elf32_ft32_relax_is_branch_target (struct bfd_link_info *link_info,
963 1.1.1.4 christos bfd * abfd, asection * sec,
964 1.1.1.4 christos bfd_vma loc)
965 1.1.1.4 christos {
966 1.1.1.4 christos Elf_Internal_Shdr *symtab_hdr;
967 1.1.1.4 christos Elf_Internal_Rela *irel, *irelend;
968 1.1.1.4 christos Elf_Internal_Sym *isym;
969 1.1.1.4 christos Elf_Internal_Sym *isymbuf = NULL;
970 1.1.1.4 christos bfd_vma symval;
971 1.1.1.4 christos struct bfd_section *isec;
972 1.1.1.4 christos
973 1.1.1.4 christos struct elf_link_hash_entry **sym_hashes;
974 1.1.1.4 christos struct elf_link_hash_entry **end_hashes;
975 1.1.1.4 christos struct elf_link_hash_entry **start_hashes;
976 1.1.1.4 christos unsigned int symcount;
977 1.1.1.4 christos
978 1.1.1.4 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
979 1.1.1.4 christos
980 1.1.1.4 christos /* Now we check for relocations pointing to ret. */
981 1.1.1.4 christos for (isec = abfd->sections; isec; isec = isec->next)
982 1.1.1.4 christos {
983 1.1.1.6 christos irel = elf_section_data (isec)->relocs;
984 1.1.1.4 christos if (irel == NULL)
985 1.1.1.4 christos irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, true);
986 1.1.1.4 christos
987 1.1.1.4 christos irelend = irel + isec->reloc_count;
988 1.1.1.4 christos
989 1.1.1.4 christos for (; irel < irelend; irel++)
990 1.1.1.4 christos {
991 1.1.1.4 christos /* Read this BFD's local symbols if we haven't done
992 1.1.1.4 christos so already. */
993 1.1.1.4 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0)
994 1.1.1.4 christos {
995 1.1.1.4 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
996 1.1.1.4 christos if (isymbuf == NULL)
997 1.1.1.4 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
998 1.1.1.4 christos symtab_hdr->sh_info, 0,
999 1.1.1.6 christos NULL, NULL, NULL);
1000 1.1.1.4 christos if (isymbuf == NULL)
1001 1.1.1.4 christos return false;
1002 1.1.1.4 christos }
1003 1.1.1.4 christos
1004 1.1.1.4 christos /* Get the value of the symbol referred to by the reloc. */
1005 1.1.1.4 christos if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1006 1.1.1.4 christos {
1007 1.1.1.4 christos /* A local symbol. */
1008 1.1.1.4 christos asection *sym_sec;
1009 1.1.1.4 christos
1010 1.1.1.4 christos isym = isymbuf + ELF32_R_SYM (irel->r_info);
1011 1.1.1.4 christos sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1012 1.1.1.4 christos symval = isym->st_value;
1013 1.1.1.4 christos /* If the reloc is absolute, it will not have
1014 1.1.1.4 christos a symbol or section associated with it. */
1015 1.1.1.4 christos if (sym_sec == sec)
1016 1.1.1.4 christos {
1017 1.1.1.4 christos symval += sym_sec->output_section->vma
1018 1.1.1.4 christos + sym_sec->output_offset;
1019 1.1.1.4 christos
1020 1.1.1.4 christos if (debug_relax)
1021 1.1.1.4 christos printf ("0x%x: Address of anchor symbol: 0x%x "
1022 1.1.1.4 christos "Address of relocation target: 0x%x \n",
1023 1.1.1.4 christos (unsigned int) irel->r_offset,
1024 1.1.1.4 christos (unsigned int) symval,
1025 1.1.1.6 christos (unsigned int) (symval + irel->r_addend));
1026 1.1.1.4 christos if ((irel->r_addend) == loc)
1027 1.1.1.4 christos return true;
1028 1.1.1.4 christos }
1029 1.1.1.4 christos }
1030 1.1.1.4 christos }
1031 1.1.1.4 christos }
1032 1.1.1.4 christos
1033 1.1.1.4 christos symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1034 1.1.1.4 christos - symtab_hdr->sh_info);
1035 1.1.1.4 christos sym_hashes = start_hashes = elf_sym_hashes (abfd);
1036 1.1.1.4 christos end_hashes = sym_hashes + symcount;
1037 1.1.1.4 christos
1038 1.1.1.4 christos for (; sym_hashes < end_hashes; sym_hashes++)
1039 1.1.1.4 christos {
1040 1.1.1.4 christos struct elf_link_hash_entry *sym_hash = *sym_hashes;
1041 1.1.1.4 christos
1042 1.1.1.4 christos /* The '--wrap SYMBOL' option is causing a pain when the object file,
1043 1.1.1.4 christos containing the definition of __wrap_SYMBOL, includes a direct
1044 1.1.1.4 christos call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
1045 1.1.1.4 christos the same symbol (which is __wrap_SYMBOL), but still exist as two
1046 1.1.1.4 christos different symbols in 'sym_hashes', we don't want to adjust
1047 1.1.1.4 christos the global symbol __wrap_SYMBOL twice.
1048 1.1.1.4 christos This check is only relevant when symbols are being wrapped. */
1049 1.1.1.4 christos if (link_info->wrap_hash != NULL)
1050 1.1.1.4 christos {
1051 1.1.1.4 christos struct elf_link_hash_entry **cur_sym_hashes;
1052 1.1.1.4 christos
1053 1.1.1.4 christos /* Loop only over the symbols whom been already checked. */
1054 1.1.1.4 christos for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
1055 1.1.1.4 christos cur_sym_hashes++)
1056 1.1.1.4 christos /* If the current symbol is identical to 'sym_hash', that means
1057 1.1.1.4 christos the symbol was already adjusted (or at least checked). */
1058 1.1.1.4 christos if (*cur_sym_hashes == sym_hash)
1059 1.1.1.4 christos break;
1060 1.1.1.4 christos
1061 1.1.1.4 christos /* Don't adjust the symbol again. */
1062 1.1.1.4 christos if (cur_sym_hashes < sym_hashes)
1063 1.1.1.4 christos continue;
1064 1.1.1.4 christos }
1065 1.1.1.4 christos
1066 1.1.1.4 christos if ((sym_hash->root.type == bfd_link_hash_defined
1067 1.1.1.4 christos || sym_hash->root.type == bfd_link_hash_defweak)
1068 1.1.1.6 christos && sym_hash->root.u.def.section == sec
1069 1.1.1.4 christos && sym_hash->root.u.def.value == loc)
1070 1.1.1.4 christos return true;
1071 1.1.1.6 christos }
1072 1.1.1.4 christos
1073 1.1.1.4 christos return false;
1074 1.1.1.6 christos }
1075 1.1.1.6 christos
1076 1.1.1.6 christos static bool
1077 1.1.1.6 christos ft32_elf_relax_section (bfd *abfd,
1078 1.1.1.6 christos asection *sec,
1079 1.1.1.4 christos struct bfd_link_info *link_info,
1080 1.1.1.4 christos bool *again)
1081 1.1.1.4 christos {
1082 1.1.1.4 christos Elf_Internal_Rela * free_relocs = NULL;
1083 1.1.1.4 christos Elf_Internal_Rela * internal_relocs;
1084 1.1.1.4 christos Elf_Internal_Rela * irelend;
1085 1.1.1.4 christos Elf_Internal_Rela * irel;
1086 1.1.1.4 christos bfd_byte * contents = NULL;
1087 1.1.1.4 christos Elf_Internal_Shdr * symtab_hdr;
1088 1.1.1.4 christos Elf_Internal_Sym * isymbuf = NULL;
1089 1.1.1.6 christos
1090 1.1.1.4 christos /* Assume nothing changes. */
1091 1.1.1.4 christos *again = false;
1092 1.1.1.4 christos
1093 1.1.1.4 christos /* We don't have to do anything for a relocatable link, if
1094 1.1.1.4 christos this section does not have relocs, or if this is not a
1095 1.1.1.4 christos code section. */
1096 1.1.1.7 christos if (bfd_link_relocatable (link_info)
1097 1.1.1.7 christos || sec->reloc_count == 0
1098 1.1.1.4 christos || (sec->flags & SEC_RELOC) == 0
1099 1.1.1.6 christos || (sec->flags & SEC_HAS_CONTENTS) == 0
1100 1.1.1.4 christos || (sec->flags & SEC_CODE) == 0)
1101 1.1.1.4 christos return true;
1102 1.1.1.4 christos
1103 1.1.1.4 christos /* Get the section contents. */
1104 1.1.1.4 christos if (elf_section_data (sec)->this_hdr.contents != NULL)
1105 1.1.1.4 christos contents = elf_section_data (sec)->this_hdr.contents;
1106 1.1.1.4 christos /* Go get them off disk. */
1107 1.1.1.4 christos else
1108 1.1.1.4 christos {
1109 1.1.1.4 christos if (! bfd_malloc_and_get_section (abfd, sec, &contents))
1110 1.1.1.4 christos goto error_return;
1111 1.1.1.4 christos elf_section_data (sec)->this_hdr.contents = contents;
1112 1.1.1.4 christos }
1113 1.1.1.4 christos
1114 1.1.1.4 christos symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1115 1.1.1.4 christos
1116 1.1.1.4 christos /* Read this BFD's local symbols if we haven't done so already. */
1117 1.1.1.4 christos if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1118 1.1.1.4 christos {
1119 1.1.1.4 christos isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1120 1.1.1.4 christos if (isymbuf == NULL)
1121 1.1.1.4 christos isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1122 1.1.1.4 christos symtab_hdr->sh_info, 0,
1123 1.1.1.4 christos NULL, NULL, NULL);
1124 1.1.1.4 christos if (isymbuf == NULL)
1125 1.1.1.4 christos goto error_return;
1126 1.1.1.4 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1127 1.1.1.4 christos }
1128 1.1.1.4 christos
1129 1.1.1.4 christos internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
1130 1.1.1.4 christos link_info->keep_memory);
1131 1.1.1.4 christos if (internal_relocs == NULL)
1132 1.1.1.4 christos goto error_return;
1133 1.1.1.4 christos if (! link_info->keep_memory)
1134 1.1.1.4 christos free_relocs = internal_relocs;
1135 1.1.1.4 christos
1136 1.1.1.4 christos /* Walk through them looking for relaxing opportunities. */
1137 1.1.1.4 christos irelend = internal_relocs + sec->reloc_count;
1138 1.1.1.4 christos
1139 1.1.1.4 christos /* Test every adjacent pair of relocs. If both have shortcodes,
1140 1.1.1.4 christos fuse them and delete the relocs. */
1141 1.1.1.4 christos irel = internal_relocs;
1142 1.1.1.4 christos while (irel < irelend - 1)
1143 1.1.1.4 christos {
1144 1.1.1.4 christos Elf_Internal_Rela * irel_next = irel + 1;
1145 1.1.1.4 christos unsigned int sc0, sc1;
1146 1.1.1.4 christos bfd_vma pc;
1147 1.1.1.4 christos
1148 1.1.1.4 christos pc = irel->r_offset;
1149 1.1.1.4 christos
1150 1.1.1.4 christos if (((pc + 4) == (irel_next->r_offset))
1151 1.1.1.4 christos && ft32_reloc_shortable (abfd, sec, isymbuf, contents, pc, irel,
1152 1.1.1.4 christos &sc0)
1153 1.1.1.4 christos && ft32_reloc_shortable (abfd, sec, isymbuf, contents, pc,
1154 1.1.1.4 christos irel_next, &sc1)
1155 1.1.1.4 christos && !elf32_ft32_relax_is_branch_target (link_info, abfd, sec,
1156 1.1.1.4 christos irel_next->r_offset))
1157 1.1.1.4 christos {
1158 1.1.1.4 christos unsigned int code30 = (sc1 << 15) | sc0;
1159 1.1.1.4 christos unsigned int code27 = code30 >> 3;
1160 1.1.1.4 christos unsigned int code3 = code30 & 7;
1161 1.1.1.4 christos static const unsigned char pat3[] = {2, 3, 4, 5, 6, 9, 10, 14};
1162 1.1.1.4 christos unsigned int pattern = pat3[code3];
1163 1.1.1.4 christos unsigned int fused = (pattern << 27) | code27;
1164 1.1.1.4 christos
1165 1.1.1.4 christos /* Move second reloc to same place as first. */
1166 1.1.1.4 christos irel_next->r_offset = irel->r_offset;
1167 1.1.1.4 christos
1168 1.1.1.4 christos /* Change both relocs to R_FT32_NONE. */
1169 1.1.1.4 christos
1170 1.1.1.4 christos if (ELF32_R_TYPE (irel->r_info) == R_FT32_18)
1171 1.1.1.4 christos {
1172 1.1.1.4 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1173 1.1.1.4 christos R_FT32_SC0);
1174 1.1.1.4 christos }
1175 1.1.1.4 christos else
1176 1.1.1.4 christos {
1177 1.1.1.4 christos irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1178 1.1.1.4 christos R_FT32_NONE);
1179 1.1.1.4 christos }
1180 1.1.1.4 christos
1181 1.1.1.4 christos if (ELF32_R_TYPE (irel_next->r_info) == R_FT32_18)
1182 1.1.1.4 christos {
1183 1.1.1.4 christos irel_next->r_info = ELF32_R_INFO (ELF32_R_SYM (irel_next->r_info),
1184 1.1.1.4 christos R_FT32_SC1);
1185 1.1.1.4 christos }
1186 1.1.1.4 christos else
1187 1.1.1.4 christos {
1188 1.1.1.4 christos irel_next->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1189 1.1.1.4 christos R_FT32_NONE);
1190 1.1.1.4 christos }
1191 1.1.1.4 christos
1192 1.1.1.4 christos /* Replace the first insn with the fused version. */
1193 1.1.1.4 christos bfd_put_32 (abfd, fused, contents + irel->r_offset);
1194 1.1.1.4 christos
1195 1.1.1.4 christos /* Delete the second insn. */
1196 1.1.1.4 christos if (!elf32_ft32_relax_delete_bytes (link_info, abfd, sec,
1197 1.1.1.4 christos irel->r_offset + 4, 4))
1198 1.1.1.4 christos goto error_return;
1199 1.1.1.4 christos
1200 1.1.1.6 christos /* That will change things, so, we should relax again.
1201 1.1.1.4 christos Note that this is not required, and it may be slow. */
1202 1.1.1.4 christos *again = true;
1203 1.1.1.4 christos
1204 1.1.1.4 christos irel += 2;
1205 1.1.1.4 christos }
1206 1.1.1.4 christos else
1207 1.1.1.4 christos {
1208 1.1.1.4 christos irel += 1;
1209 1.1.1.4 christos }
1210 1.1.1.4 christos }
1211 1.1.1.4 christos
1212 1.1.1.4 christos if (isymbuf != NULL
1213 1.1.1.4 christos && symtab_hdr->contents != (unsigned char *) isymbuf)
1214 1.1.1.4 christos {
1215 1.1.1.4 christos if (! link_info->keep_memory)
1216 1.1.1.4 christos free (isymbuf);
1217 1.1.1.4 christos else
1218 1.1.1.4 christos /* Cache the symbols for elf_link_input_bfd. */
1219 1.1.1.4 christos symtab_hdr->contents = (unsigned char *) isymbuf;
1220 1.1.1.4 christos }
1221 1.1.1.4 christos
1222 1.1.1.4 christos if (contents != NULL
1223 1.1.1.4 christos && elf_section_data (sec)->this_hdr.contents != contents)
1224 1.1.1.4 christos {
1225 1.1.1.4 christos if (! link_info->keep_memory)
1226 1.1.1.4 christos free (contents);
1227 1.1.1.4 christos else
1228 1.1.1.4 christos /* Cache the section contents for elf_link_input_bfd. */
1229 1.1.1.4 christos elf_section_data (sec)->this_hdr.contents = contents;
1230 1.1.1.4 christos
1231 1.1.1.5 christos }
1232 1.1.1.4 christos
1233 1.1.1.4 christos if (elf_section_data (sec)->relocs != internal_relocs)
1234 1.1.1.6 christos free (internal_relocs);
1235 1.1.1.4 christos
1236 1.1.1.4 christos return true;
1237 1.1.1.5 christos
1238 1.1.1.4 christos error_return:
1239 1.1.1.6 christos free (free_relocs);
1240 1.1.1.4 christos
1241 1.1.1.4 christos return true;
1242 1.1 christos }
1243 1.1 christos
1244 1.1 christos #define ELF_ARCH bfd_arch_ft32
1246 1.1 christos #define ELF_MACHINE_CODE EM_FT32
1247 1.1 christos #define ELF_MAXPAGESIZE 0x1
1248 1.1 christos
1249 1.1 christos #define TARGET_LITTLE_SYM ft32_elf32_vec
1250 1.1 christos #define TARGET_LITTLE_NAME "elf32-ft32"
1251 1.1 christos
1252 1.1 christos #define elf_info_to_howto_rel NULL
1253 1.1 christos #define elf_info_to_howto ft32_info_to_howto_rela
1254 1.1 christos #define elf_backend_relocate_section ft32_elf_relocate_section
1255 1.1 christos
1256 1.1 christos #define elf_backend_can_gc_sections 1
1257 1.1 christos #define elf_backend_rela_normal 1
1258 1.1 christos
1259 1.1.1.4 christos #define bfd_elf32_bfd_reloc_type_lookup ft32_reloc_type_lookup
1260 1.1.1.4 christos #define bfd_elf32_bfd_reloc_name_lookup ft32_reloc_name_lookup
1261 1.1 christos
1262 #define bfd_elf32_bfd_relax_section ft32_elf_relax_section
1263
1264 #include "elf32-target.h"
1265