Add support for parallel instructions.
[deliverable/binutils-gdb.git] / bfd / elf32-txvu.c
1 /* TXVU-specific support for 32-bit ELF.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #include "bfd.h"
21 #include "sysdep.h"
22 #include "libbfd.h"
23 #include "elf-bfd.h"
24 #include "elf/txvu.h"
25
26 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
27 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
28 static void txvu_info_to_howto_rel
29 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
30 static boolean txvu_elf_relocate_section
31 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
32 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
33
34 /* Use RELA, not REL. REL incurs complications one would rather not
35 deal with. */
36 /*#define USE_REL*/
37
38 static reloc_howto_type txvu_elf_howto_table[] =
39 {
40 /* This reloc does nothing. */
41 HOWTO (R_TXVU_NONE, /* type */
42 0, /* rightshift */
43 2, /* size (0 = byte, 1 = short, 2 = long) */
44 32, /* bitsize */
45 false, /* pc_relative */
46 0, /* bitpos */
47 complain_overflow_bitfield, /* complain_on_overflow */
48 bfd_elf_generic_reloc, /* special_function */
49 "R_TXVU_NONE", /* name */
50 false, /* partial_inplace */
51 0, /* src_mask */
52 0, /* dst_mask */
53 false), /* pcrel_offset */
54
55 /* insert reloc entries here */
56 };
57 \f
58 /* Map BFD reloc types to TXVU ELF reloc types. */
59
60 struct txvu_reloc_map
61 {
62 unsigned char bfd_reloc_val;
63 unsigned char elf_reloc_val;
64 };
65
66 static const struct txvu_reloc_map txvu_reloc_map[] =
67 {
68 { BFD_RELOC_NONE, R_TXVU_NONE },
69 /* insert reloc entries here */
70 };
71
72 static reloc_howto_type *
73 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
74 bfd *abfd;
75 bfd_reloc_code_real_type code;
76 {
77 unsigned int i;
78
79 for (i = 0;
80 i < sizeof (txvu_reloc_map) / sizeof (struct txvu_reloc_map);
81 i++)
82 {
83 if (txvu_reloc_map[i].bfd_reloc_val == code)
84 return &txvu_elf_howto_table[txvu_reloc_map[i].elf_reloc_val];
85 }
86
87 return NULL;
88 }
89
90 /* Set the howto pointer for an TXVU ELF reloc. */
91
92 static void
93 txvu_info_to_howto_rel (abfd, cache_ptr, dst)
94 bfd *abfd;
95 arelent *cache_ptr;
96 Elf32_Internal_Rela *dst;
97 {
98 unsigned int r_type = ELF32_R_TYPE (dst->r_info);
99 BFD_ASSERT (r_type < (unsigned int) R_TXVU_max);
100 cache_ptr->howto = &txvu_elf_howto_table[r_type];
101 }
102 \f
103 /* Relocate a TXVU ELF section.
104
105 The RELOCATE_SECTION function is called by the new ELF backend linker
106 to handle the relocations for a section.
107
108 The relocs are always passed as Rela structures; if the section
109 actually uses Rel structures, the r_addend field will always be
110 zero.
111
112 This function is responsible for adjust the section contents as
113 necessary, and (if using Rela relocs and generating a
114 relocateable output file) adjusting the reloc addend as
115 necessary.
116
117 This function does not have to worry about setting the reloc
118 address or the reloc symbol index.
119
120 LOCAL_SYMS is a pointer to the swapped in local symbols.
121
122 LOCAL_SECTIONS is an array giving the section in the input file
123 corresponding to the st_shndx field of each local symbol.
124
125 The global hash table entry for the global symbols can be found
126 via elf_sym_hashes (input_bfd).
127
128 When generating relocateable output, this function must handle
129 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
130 going to be the section symbol corresponding to the output
131 section, which means that the addend must be adjusted
132 accordingly. */
133
134 static boolean
135 txvu_elf_relocate_section (output_bfd, info, input_bfd, input_section,
136 contents, relocs, local_syms, local_sections)
137 bfd *output_bfd;
138 struct bfd_link_info *info;
139 bfd *input_bfd;
140 asection *input_section;
141 bfd_byte *contents;
142 Elf_Internal_Rela *relocs;
143 Elf_Internal_Sym *local_syms;
144 asection **local_sections;
145 {
146 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
147 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
148 Elf_Internal_Rela *rel, *relend;
149 bfd *dynobj = elf_hash_table (info)->dynobj;
150 /* Assume success. */
151 boolean ret = true;
152
153 rel = relocs;
154 relend = relocs + input_section->reloc_count;
155 for (; rel < relend; rel++)
156 {
157 int r_type;
158 reloc_howto_type *howto;
159 unsigned long r_symndx;
160 /* We can't modify r_addend here as elf_link_input_bfd has an assert to
161 ensure it's zero (we use REL relocs, not RELA). Therefore this
162 should be assigning zero to `addend', but for clarity we use
163 `r_addend'. */
164 /* ??? The previous comment is old, revisit and delete. */
165 bfd_vma addend = rel->r_addend;
166 bfd_vma offset = rel->r_offset;
167 struct elf_link_hash_entry *h;
168 Elf_Internal_Sym *sym;
169 asection *sec;
170 const char *sym_name;
171 bfd_reloc_status_type r;
172 const char *errmsg = NULL;
173
174 r_type = ELF32_R_TYPE (rel->r_info);
175 if (r_type < 0 || r_type >= (int) R_TXVU_max)
176 {
177 (*_bfd_error_handler) ("%s: unknown relocation type %d",
178 bfd_get_filename (input_bfd),
179 (int) r_type);
180 bfd_set_error (bfd_error_bad_value);
181 ret = false;
182 continue;
183 }
184
185 howto = txvu_elf_howto_table + r_type;
186 r_symndx = ELF32_R_SYM (rel->r_info);
187
188 if (info->relocateable)
189 {
190 /* This is a relocateable link. We don't have to change
191 anything, unless the reloc is against a section symbol,
192 in which case we have to adjust according to where the
193 section symbol winds up in the output section. */
194 sec = NULL;
195 if (r_symndx >= symtab_hdr->sh_info)
196 {
197 /* External symbol. */
198 continue;
199 }
200
201 /* Local symbol. */
202 sym = local_syms + r_symndx;
203 sym_name = "<local symbol>";
204 /* STT_SECTION: symbol is associated with a section. */
205 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
206 {
207 /* Symbol isn't associated with a section. Nothing to do. */
208 continue;
209 }
210
211 sec = local_sections[r_symndx];
212 addend += sec->output_offset + sym->st_value;
213 rel->r_addend = addend;
214
215 /* Addends are stored with relocs. We're done. */
216 continue;
217 }
218 else
219 {
220 bfd_vma relocation;
221
222 /* This is a final link. */
223 h = NULL;
224 sym = NULL;
225 sec = NULL;
226
227 if (r_symndx < symtab_hdr->sh_info)
228 {
229 /* Local symbol. */
230 sym = local_syms + r_symndx;
231 sec = local_sections[r_symndx];
232 sym_name = "<local symbol>";
233 relocation = (sec->output_section->vma
234 + sec->output_offset
235 + sym->st_value);
236 }
237 else
238 {
239 /* External symbol. */
240 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
241 while (h->root.type == bfd_link_hash_indirect
242 || h->root.type == bfd_link_hash_warning)
243 h = (struct elf_link_hash_entry *) h->root.u.i.link;
244 sym_name = h->root.root.string;
245
246 if (h->root.type == bfd_link_hash_defined
247 || h->root.type == bfd_link_hash_defweak)
248 {
249 sec = h->root.u.def.section;
250 if (sec->output_section == NULL)
251 relocation = 0;
252 else
253 relocation = (h->root.u.def.value
254 + sec->output_section->vma
255 + sec->output_offset);
256 }
257 else if (h->root.type == bfd_link_hash_undefweak)
258 relocation = 0;
259 else
260 {
261 if (! ((*info->callbacks->undefined_symbol)
262 (info, h->root.root.string, input_bfd,
263 input_section, offset)))
264 return false;
265 relocation = 0;
266 }
267 }
268
269 /* Sanity check the address. */
270 if (offset > input_section->_raw_size)
271 {
272 r = bfd_reloc_outofrange;
273 goto check_reloc;
274 }
275
276 switch ((int) r_type)
277 {
278 /* insert reloc handling code here */
279 default :
280 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
281 contents, offset,
282 relocation, addend);
283 break;
284 }
285 }
286
287 check_reloc:
288
289 if (r != bfd_reloc_ok)
290 {
291 /* FIXME: This should be generic enough to go in a utility. */
292 const char *name;
293
294 if (h != NULL)
295 name = h->root.root.string;
296 else
297 {
298 name = (bfd_elf_string_from_elf_section
299 (input_bfd, symtab_hdr->sh_link, sym->st_name));
300 if (name == NULL || *name == '\0')
301 name = bfd_section_name (input_bfd, sec);
302 }
303
304 if (errmsg != NULL)
305 goto common_error;
306
307 switch (r)
308 {
309 case bfd_reloc_overflow:
310 if (! ((*info->callbacks->reloc_overflow)
311 (info, name, howto->name, (bfd_vma) 0,
312 input_bfd, input_section, offset)))
313 return false;
314 break;
315
316 case bfd_reloc_undefined:
317 if (! ((*info->callbacks->undefined_symbol)
318 (info, name, input_bfd, input_section,
319 offset)))
320 return false;
321 break;
322
323 case bfd_reloc_outofrange:
324 errmsg = "internal error: out of range error";
325 goto common_error;
326
327 case bfd_reloc_notsupported:
328 errmsg = "internal error: unsupported relocation error";
329 goto common_error;
330
331 case bfd_reloc_dangerous:
332 errmsg = "internal error: dangerous error";
333 goto common_error;
334
335 default:
336 errmsg = "internal error: unknown error";
337 /* fall through */
338
339 common_error:
340 if (!((*info->callbacks->warning)
341 (info, errmsg, name, input_bfd, input_section,
342 offset)))
343 return false;
344 break;
345 }
346 }
347 }
348
349 return ret;
350 }
351 \f
352 #define ELF_ARCH bfd_arch_txvu
353 #define ELF_MACHINE_CODE EM_CYGNUS_TXVU
354 #define ELF_MAXPAGESIZE 0x1000
355
356 #define TARGET_BIG_SYM bfd_elf32_txvu_vec
357 #define TARGET_BIG_NAME "elf32-txvu"
358
359 #define elf_info_to_howto txvu_info_to_howto_rel
360 #define elf_backend_relocate_section txvu_elf_relocate_section
361
362 #include "elf32-target.h"
This page took 0.037874 seconds and 4 git commands to generate.