1 /* BFD back-end for Hitachi Super-H COFF binaries.
2 Copyright 1993, 1994 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4 Written by Steve Chamberlain, <sac@cygnus.com>.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
28 #include "coff/internal.h"
31 static bfd_reloc_status_type
sh_reloc();
33 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
35 #define COFF_LONG_FILENAMES
37 static 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};
42 #define BADMAG(x) SHBADMAG(x)
43 #define SH 1 /* Customize coffcode.h */
45 #define __A_MAGIC_SET__
47 /* Code to swap in the reloc */
48 #define SWAP_OUT_RELOC_EXTRA(abfd, src, dst) \
49 dst->r_stuff[0] = 'S'; \
50 dst->r_stuff[1] = 'C';
52 /* Code to turn a r_type into a howto ptr, uses the above howto table. */
54 get_symbol_value (symbol
)
59 if (bfd_is_com_section (symbol
->section
))
65 relocation
= symbol
->value
+
66 symbol
->section
->output_section
->vma
+
67 symbol
->section
->output_offset
;
73 #define RTYPE2HOWTO(x,y) ((x)->howto = &r_imm32)
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
86 FIXME: This macro refers to symbols and asect; these are from the
87 calling function, not the macro arguments. */
89 #define CALC_ADDEND(abfd, ptr, reloc, cache_ptr) \
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)); \
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); \
104 cache_ptr->addend = 0; \
107 /* this function is in charge of performing all the 29k relocations */
109 static bfd_reloc_status_type
110 sh_reloc (abfd
, reloc_entry
, symbol_in
, data
, input_section
, output_bfd
,
113 arelent
*reloc_entry
;
116 asection
*input_section
;
118 char **error_message
;
120 /* the consth relocation comes in two parts, we have to remember
121 the state between calls, in these variables */
123 unsigned long sym_value
;
124 unsigned short r_type
;
126 unsigned long addr
= reloc_entry
->address
; /*+ input_section->vma*/
127 bfd_byte
*hit_data
=addr
+ (bfd_byte
*)(data
);
129 r_type
= reloc_entry
->howto
->type
;
132 /* Partial linking - do nothing */
133 reloc_entry
->address
+= input_section
->output_offset
;
137 if (symbol_in
!= NULL
138 && bfd_is_und_section (symbol_in
->section
))
140 /* Keep the state machine happy in case we're called again */
141 return (bfd_reloc_undefined
);
145 sym_value
= get_symbol_value(symbol_in
);
150 /* We ignore the previous contents ! */
151 insn
= sym_value
+ reloc_entry
->addend
;
152 bfd_put_32(abfd
, insn
, hit_data
);
155 *error_message
= "Unrecognized reloc";
156 return (bfd_reloc_dangerous
);
160 return(bfd_reloc_ok
);
163 /* The reloc processing routine for the optimized COFF linker. */
166 coff_sh_relocate_section (output_bfd
, info
, input_bfd
, input_section
,
167 contents
, relocs
, syms
, sections
)
169 struct bfd_link_info
*info
;
171 asection
*input_section
;
173 struct internal_reloc
*relocs
;
174 struct internal_syment
*syms
;
177 struct internal_reloc
*rel
;
178 struct internal_reloc
*relend
;
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
)
188 relend
= rel
+ input_section
->reloc_count
;
189 for (; rel
< relend
; rel
++)
193 struct coff_link_hash_entry
*h
;
194 struct internal_syment
*sym
;
198 symndx
= rel
->r_symndx
;
199 loc
= contents
+ rel
->r_vaddr
- input_section
->vma
;
204 h
= obj_coff_sym_hashes (input_bfd
)[symndx
];
214 sec
= bfd_abs_section_ptr
;
218 sec
= sections
[symndx
];
219 val
= (sec
->output_section
->vma
228 if (h
->root
.type
== bfd_link_hash_defined
)
230 sec
= h
->root
.u
.def
.section
;
231 val
= (h
->root
.u
.def
.value
232 + sec
->output_section
->vma
233 + sec
->output_offset
);
237 if (! ((*info
->callbacks
->undefined_symbol
)
238 (info
, h
->root
.root
.string
, input_bfd
, input_section
,
239 rel
->r_vaddr
- input_section
->vma
)))
247 bfd_set_error (bfd_error_bad_value
);
252 long x
= bfd_get_32 (input_bfd
, loc
);
254 bfd_put_32 (input_bfd
, x
, loc
);
265 #define coff_relocate_section coff_sh_relocate_section
267 #include "coffcode.h"
269 const bfd_target shcoff_vec
=
271 "coff-sh", /* name */
272 bfd_target_coff_flavour
,
273 true, /* data byte order is big */
274 true, /* header byte order is big */
276 (HAS_RELOC
| EXEC_P
| /* object flags */
277 HAS_LINENO
| HAS_DEBUG
|
278 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| BFD_IS_RELAXABLE
),
280 (SEC_HAS_CONTENTS
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
281 '_', /* leading symbol underscore */
282 '/', /* ar_pad_char */
283 15, /* ar_max_namelen */
284 2, /* minimum section alignment */
285 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
286 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
287 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* data */
288 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
289 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
290 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* hdrs */
292 {_bfd_dummy_target
, coff_object_p
, /* bfd_check_format */
293 bfd_generic_archive_p
, _bfd_dummy_target
},
294 {bfd_false
, coff_mkobject
, _bfd_generic_mkarchive
, /* bfd_set_format */
296 {bfd_false
, coff_write_object_contents
, /* bfd_write_contents */
297 _bfd_write_archive_contents
, bfd_false
},
299 BFD_JUMP_TABLE_GENERIC (coff
),
300 BFD_JUMP_TABLE_COPY (coff
),
301 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
302 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_coff
),
303 BFD_JUMP_TABLE_SYMBOLS (coff
),
304 BFD_JUMP_TABLE_RELOCS (coff
),
305 BFD_JUMP_TABLE_WRITE (coff
),
306 BFD_JUMP_TABLE_LINK (coff
),
307 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),