1 /* TXVU-specific support for 32-bit ELF.
2 Copyright (C) 1997 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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
**));
34 /* Use RELA, not REL. REL incurs complications one would rather not
38 static reloc_howto_type txvu_elf_howto_table
[] =
40 /* This reloc does nothing. */
41 HOWTO (R_TXVU_NONE
, /* type */
43 2, /* size (0 = byte, 1 = short, 2 = long) */
45 false, /* pc_relative */
47 complain_overflow_bitfield
, /* complain_on_overflow */
48 bfd_elf_generic_reloc
, /* special_function */
49 "R_TXVU_NONE", /* name */
50 false, /* partial_inplace */
53 false), /* pcrel_offset */
55 /* insert reloc entries here */
58 /* Map BFD reloc types to TXVU ELF reloc types. */
62 unsigned char bfd_reloc_val
;
63 unsigned char elf_reloc_val
;
66 static const struct txvu_reloc_map txvu_reloc_map
[] =
68 { BFD_RELOC_NONE
, R_TXVU_NONE
},
69 /* insert reloc entries here */
72 static reloc_howto_type
*
73 bfd_elf32_bfd_reloc_type_lookup (abfd
, code
)
75 bfd_reloc_code_real_type code
;
80 i
< sizeof (txvu_reloc_map
) / sizeof (struct txvu_reloc_map
);
83 if (txvu_reloc_map
[i
].bfd_reloc_val
== code
)
84 return &txvu_elf_howto_table
[txvu_reloc_map
[i
].elf_reloc_val
];
90 /* Set the howto pointer for an TXVU ELF reloc. */
93 txvu_info_to_howto_rel (abfd
, cache_ptr
, dst
)
96 Elf32_Internal_Rela
*dst
;
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
];
103 /* Relocate a TXVU ELF section.
105 The RELOCATE_SECTION function is called by the new ELF backend linker
106 to handle the relocations for a section.
108 The relocs are always passed as Rela structures; if the section
109 actually uses Rel structures, the r_addend field will always be
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
117 This function does not have to worry about setting the reloc
118 address or the reloc symbol index.
120 LOCAL_SYMS is a pointer to the swapped in local symbols.
122 LOCAL_SECTIONS is an array giving the section in the input file
123 corresponding to the st_shndx field of each local symbol.
125 The global hash table entry for the global symbols can be found
126 via elf_sym_hashes (input_bfd).
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
135 txvu_elf_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
136 contents
, relocs
, local_syms
, local_sections
)
138 struct bfd_link_info
*info
;
140 asection
*input_section
;
142 Elf_Internal_Rela
*relocs
;
143 Elf_Internal_Sym
*local_syms
;
144 asection
**local_sections
;
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. */
154 relend
= relocs
+ input_section
->reloc_count
;
155 for (; rel
< relend
; rel
++)
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
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
;
170 const char *sym_name
;
171 bfd_reloc_status_type r
;
172 const char *errmsg
= NULL
;
174 r_type
= ELF32_R_TYPE (rel
->r_info
);
175 if (r_type
< 0 || r_type
>= (int) R_TXVU_max
)
177 (*_bfd_error_handler
) ("%s: unknown relocation type %d",
178 bfd_get_filename (input_bfd
),
180 bfd_set_error (bfd_error_bad_value
);
185 howto
= txvu_elf_howto_table
+ r_type
;
186 r_symndx
= ELF32_R_SYM (rel
->r_info
);
188 if (info
->relocateable
)
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. */
195 if (r_symndx
>= symtab_hdr
->sh_info
)
197 /* External 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
)
207 /* Symbol isn't associated with a section. Nothing to do. */
211 sec
= local_sections
[r_symndx
];
212 addend
+= sec
->output_offset
+ sym
->st_value
;
213 rel
->r_addend
= addend
;
215 /* Addends are stored with relocs. We're done. */
222 /* This is a final link. */
227 if (r_symndx
< symtab_hdr
->sh_info
)
230 sym
= local_syms
+ r_symndx
;
231 sec
= local_sections
[r_symndx
];
232 sym_name
= "<local symbol>";
233 relocation
= (sec
->output_section
->vma
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
;
246 if (h
->root
.type
== bfd_link_hash_defined
247 || h
->root
.type
== bfd_link_hash_defweak
)
249 sec
= h
->root
.u
.def
.section
;
250 if (sec
->output_section
== NULL
)
253 relocation
= (h
->root
.u
.def
.value
254 + sec
->output_section
->vma
255 + sec
->output_offset
);
257 else if (h
->root
.type
== bfd_link_hash_undefweak
)
261 if (! ((*info
->callbacks
->undefined_symbol
)
262 (info
, h
->root
.root
.string
, input_bfd
,
263 input_section
, offset
)))
269 /* Sanity check the address. */
270 if (offset
> input_section
->_raw_size
)
272 r
= bfd_reloc_outofrange
;
276 switch ((int) r_type
)
278 /* insert reloc handling code here */
280 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
289 if (r
!= bfd_reloc_ok
)
291 /* FIXME: This should be generic enough to go in a utility. */
295 name
= h
->root
.root
.string
;
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
);
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
)))
316 case bfd_reloc_undefined
:
317 if (! ((*info
->callbacks
->undefined_symbol
)
318 (info
, name
, input_bfd
, input_section
,
323 case bfd_reloc_outofrange
:
324 errmsg
= "internal error: out of range error";
327 case bfd_reloc_notsupported
:
328 errmsg
= "internal error: unsupported relocation error";
331 case bfd_reloc_dangerous
:
332 errmsg
= "internal error: dangerous error";
336 errmsg
= "internal error: unknown error";
340 if (!((*info
->callbacks
->warning
)
341 (info
, errmsg
, name
, input_bfd
, input_section
,
352 #define ELF_ARCH bfd_arch_txvu
353 #define ELF_MACHINE_CODE EM_CYGNUS_TXVU
354 #define ELF_MAXPAGESIZE 0x1000
356 #define TARGET_BIG_SYM bfd_elf32_txvu_vec
357 #define TARGET_BIG_NAME "elf32-txvu"
359 #define elf_info_to_howto txvu_info_to_howto_rel
360 #define elf_backend_relocate_section txvu_elf_relocate_section
362 #include "elf32-target.h"