* coff-h8300.c (COFF_LONG_FILENAMES): Define.
[deliverable/binutils-gdb.git] / bfd / coff-sh.c
CommitLineData
46dd0622 1/* BFD back-end for Hitachi Super-H COFF binaries.
51fbf454 2 Copyright 1993, 1994, 1995 Free Software Foundation, Inc.
46dd0622
SC
3 Contributed by Cygnus Support.
4 Written by Steve Chamberlain, <sac@cygnus.com>.
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22#include "bfd.h"
23#include "sysdep.h"
46dd0622 24#include "obstack.h"
6812b607
ILT
25#include "libbfd.h"
26#include "bfdlink.h"
46dd0622
SC
27#include "coff/sh.h"
28#include "coff/internal.h"
29#include "libcoff.h"
46dd0622 30
cf345e36 31static bfd_reloc_status_type sh_reloc();
46dd0622 32
f6f350fe
KR
33#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
34
7a1d4567 35/*#define COFF_LONG_FILENAMES*/
46dd0622 36
cf345e36
SC
37static reloc_howto_type r_imm32 =
38 {R_SH_IMM32, 0, 2, 32, false, 0,
39 complain_overflow_bitfield, sh_reloc,"r_imm32", true, 0xffffffff,0xffffffff, false};
46dd0622 40
46dd0622 41
46dd0622
SC
42#define BADMAG(x) SHBADMAG(x)
43#define SH 1 /* Customize coffcode.h */
44
45#define __A_MAGIC_SET__
46
47/* Code to swap in the reloc */
46dd0622
SC
48#define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
49 dst->r_stuff[0] = 'S'; \
50 dst->r_stuff[1] = 'C';
51
f6f350fe 52/* Code to turn a r_type into a howto ptr, uses the above howto table. */
cf345e36
SC
53static long
54get_symbol_value (symbol)
55 asymbol *symbol;
56{
57 long relocation = 0;
58
59 if (bfd_is_com_section (symbol->section))
60 {
61 relocation = 0;
62 }
63 else
64 {
65 relocation = symbol->value +
66 symbol->section->output_section->vma +
67 symbol->section->output_offset;
68 }
69
70 return(relocation);
71}
46dd0622 72
cf345e36 73#define RTYPE2HOWTO(x,y) ((x)->howto = &r_imm32)
46dd0622 74
cf345e36
SC
75
76/* Compute the addend of a reloc. If the reloc is to a common symbol,
77 the object file contains the value of the common symbol. By the
78 time this is called, the linker may be using a different symbol
79 from a different object file with a different value. Therefore, we
80 hack wildly to locate the original symbol from this file so that we
81 can make the correct adjustment. This macro sets coffsym to the
82 symbol from the original file, and uses it to set the addend value
83 correctly. If this is not a common symbol, the usual addend
84 calculation is done, except that an additional tweak is needed for
85 PC relative relocs.
86 FIXME: This macro refers to symbols and asect; these are from the
87 calling function, not the macro arguments. */
88
89#define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
90 { \
91 coff_symbol_type *coffsym = (coff_symbol_type *) NULL; \
92 if (ptr && bfd_asymbol_bfd (ptr) != abfd) \
93 coffsym = (obj_symbols (abfd) \
94 + (cache_ptr->sym_ptr_ptr - symbols)); \
95 else if (ptr) \
96 coffsym = coff_symbol_from (abfd, ptr); \
97 if (coffsym != (coff_symbol_type *) NULL \
98 && coffsym->native->u.syment.n_scnum == 0) \
99 cache_ptr->addend = - coffsym->native->u.syment.n_value; \
100 else if (ptr && bfd_asymbol_bfd (ptr) == abfd \
101 && ptr->section != (asection *) NULL) \
102 cache_ptr->addend = - (ptr->section->vma + ptr->value); \
103 else \
104 cache_ptr->addend = 0; \
105 }
106
cf345e36
SC
107/* this function is in charge of performing all the 29k relocations */
108
109static bfd_reloc_status_type
110sh_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
111 error_message)
112 bfd *abfd;
113 arelent *reloc_entry;
114 asymbol *symbol_in;
115 PTR data;
116 asection *input_section;
117 bfd *output_bfd;
118 char **error_message;
119{
120 /* the consth relocation comes in two parts, we have to remember
121 the state between calls, in these variables */
122 unsigned long insn;
123 unsigned long sym_value;
124 unsigned short r_type;
125
126 unsigned long addr = reloc_entry->address ; /*+ input_section->vma*/
127 bfd_byte *hit_data =addr + (bfd_byte *)(data);
128
129 r_type = reloc_entry->howto->type;
130
131 if (output_bfd) {
132 /* Partial linking - do nothing */
133 reloc_entry->address += input_section->output_offset;
134 return bfd_reloc_ok;
135 }
136
137 if (symbol_in != NULL
138 && bfd_is_und_section (symbol_in->section))
139 {
140 /* Keep the state machine happy in case we're called again */
141 return (bfd_reloc_undefined);
142 }
143
144
145 sym_value = get_symbol_value(symbol_in);
146
147 switch (r_type)
148 {
149 case R_SH_IMM32:
cf345e36 150 insn = sym_value + reloc_entry->addend;
6e3acf74 151 insn += bfd_get_32 (abfd, hit_data);
cf345e36
SC
152 bfd_put_32(abfd, insn, hit_data);
153 break;
154 default:
155 *error_message = "Unrecognized reloc";
156 return (bfd_reloc_dangerous);
157 }
158
159
160 return(bfd_reloc_ok);
161}
162
163/* The reloc processing routine for the optimized COFF linker. */
164
165static boolean
166coff_sh_relocate_section (output_bfd, info, input_bfd, input_section,
167 contents, relocs, syms, sections)
168 bfd *output_bfd;
169 struct bfd_link_info *info;
170 bfd *input_bfd;
171 asection *input_section;
172 bfd_byte *contents;
173 struct internal_reloc *relocs;
174 struct internal_syment *syms;
175 asection **sections;
176{
177 struct internal_reloc *rel;
178 struct internal_reloc *relend;
179
180 /* If we are performing a relocateable link, we don't need to do a
181 thing. The caller will take care of adjusting the reloc
182 addresses and symbol indices. */
183 if (info->relocateable)
184 return true;
185
186
187 rel = relocs;
188 relend = rel + input_section->reloc_count;
189 for (; rel < relend; rel++)
190 {
191 long symndx;
192 bfd_byte *loc;
193 struct coff_link_hash_entry *h;
194 struct internal_syment *sym;
195 asection *sec;
196 bfd_vma val;
cf345e36
SC
197
198 symndx = rel->r_symndx;
199 loc = contents + rel->r_vaddr - input_section->vma;
200
201 if (symndx == -1)
202 h = NULL;
203 else
204 h = obj_coff_sym_hashes (input_bfd)[symndx];
205
206 sym = NULL;
207 sec = NULL;
208 val = 0;
209
210
211 if (h == NULL)
212 {
213 if (symndx == -1)
214 sec = bfd_abs_section_ptr;
215 else
216 {
217 sym = syms + symndx;
218 sec = sections[symndx];
219 val = (sec->output_section->vma
220 + sec->output_offset
221 + sym->n_value
cf345e36
SC
222 - sec->vma);
223 }
224 }
225 else
226 {
227 if (h->root.type == bfd_link_hash_defined)
228 {
229 sec = h->root.u.def.section;
230 val = (h->root.u.def.value
231 + sec->output_section->vma
232 + sec->output_offset);
233 }
234 else
235 {
236 if (! ((*info->callbacks->undefined_symbol)
237 (info, h->root.root.string, input_bfd, input_section,
238 rel->r_vaddr - input_section->vma)))
239 return false;
240 }
241 }
242
243 switch (rel->r_type)
244 {
245 default:
246 bfd_set_error (bfd_error_bad_value);
247 return false;
248
249 case R_SH_IMM32:
250 {
251 long x = bfd_get_32 (input_bfd, loc);
252 x += val;
253 bfd_put_32 (input_bfd, x, loc);
254
255 }
256
257 break;
258 }
259 }
260
261 return true;
262}
46dd0622 263
cf345e36 264#define coff_relocate_section coff_sh_relocate_section
46dd0622
SC
265#include "coffcode.h"
266
2f3508ad 267const bfd_target shcoff_vec =
46dd0622
SC
268{
269 "coff-sh", /* name */
270 bfd_target_coff_flavour,
271 true, /* data byte order is big */
272 true, /* header byte order is big */
273
274 (HAS_RELOC | EXEC_P | /* object flags */
275 HAS_LINENO | HAS_DEBUG |
6812b607 276 HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
46dd0622
SC
277
278 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
279 '_', /* leading symbol underscore */
280 '/', /* ar_pad_char */
281 15, /* ar_max_namelen */
282 2, /* minimum section alignment */
cf345e36 283 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
6812b607
ILT
284 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
285 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* data */
cf345e36 286 bfd_getb64, bfd_getb_signed_64, bfd_putb64,
6812b607
ILT
287 bfd_getb32, bfd_getb_signed_32, bfd_putb32,
288 bfd_getb16, bfd_getb_signed_16, bfd_putb16, /* hdrs */
46dd0622
SC
289
290 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
291 bfd_generic_archive_p, _bfd_dummy_target},
292 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
293 bfd_false},
294 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
295 _bfd_write_archive_contents, bfd_false},
296
6812b607
ILT
297 BFD_JUMP_TABLE_GENERIC (coff),
298 BFD_JUMP_TABLE_COPY (coff),
299 BFD_JUMP_TABLE_CORE (_bfd_nocore),
300 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
301 BFD_JUMP_TABLE_SYMBOLS (coff),
302 BFD_JUMP_TABLE_RELOCS (coff),
303 BFD_JUMP_TABLE_WRITE (coff),
304 BFD_JUMP_TABLE_LINK (coff),
2f3508ad 305 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
6812b607 306
46dd0622
SC
307 COFF_SWAP_TABLE,
308};
cf345e36 309
7a1d4567
SC
310const bfd_target shlcoff_vec =
311{
312 "coff-shl", /* name */
313 bfd_target_coff_flavour,
314 false, /* data byte order is little */
315 false, /* header byte order is little endian too*/
316
317 (HAS_RELOC | EXEC_P | /* object flags */
318 HAS_LINENO | HAS_DEBUG |
319 HAS_SYMS | HAS_LOCALS | WP_TEXT | BFD_IS_RELAXABLE ),
320
321 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
322 '_', /* leading symbol underscore */
323 '/', /* ar_pad_char */
324 15, /* ar_max_namelen */
325 2, /* minimum section alignment */
326 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
327 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
328 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
329 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
330 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
331 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
332
333/* Note that we use a special archive recognizer.
334 This is so that we only use one archive format for both
335 object file types */
336 {_bfd_dummy_target, coff_object_p, /* bfd_check_format */
6e3acf74 337 _bfd_dummy_target, _bfd_dummy_target},
7a1d4567
SC
338 {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format */
339 bfd_false},
340 {bfd_false, coff_write_object_contents, /* bfd_write_contents */
341 _bfd_write_archive_contents, bfd_false},
342
343 BFD_JUMP_TABLE_GENERIC (coff),
344 BFD_JUMP_TABLE_COPY (coff),
345 BFD_JUMP_TABLE_CORE (_bfd_nocore),
346 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff),
347 BFD_JUMP_TABLE_SYMBOLS (coff),
348 BFD_JUMP_TABLE_RELOCS (coff),
349 BFD_JUMP_TABLE_WRITE (coff),
350 BFD_JUMP_TABLE_LINK (coff),
351 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
352
353 COFF_SWAP_TABLE,
354};
355
This page took 0.094021 seconds and 4 git commands to generate.