Switch sources over to use the GPL version 3
[deliverable/binutils-gdb.git] / bfd / coff-m88k.c
CommitLineData
5c4491d3 1/* BFD back-end for Motorola 88000 COFF "Binary Compatibility Standard" files.
dc810e39 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3db64b00 3 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
252b5132
RH
4 Written by Cygnus Support.
5
cd123cb7 6 This file is part of BFD, the Binary File Descriptor library.
252b5132 7
cd123cb7
NC
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 3 of the License, or
11 (at your option) any later version.
252b5132 12
cd123cb7
NC
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.
252b5132 17
cd123cb7
NC
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., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
252b5132
RH
22
23#define M88 1 /* Customize various include files */
252b5132 24#include "sysdep.h"
3db64b00 25#include "bfd.h"
252b5132
RH
26#include "libbfd.h"
27#include "coff/m88k.h"
28#include "coff/internal.h"
29#include "libcoff.h"
30
b34976b6 31static bfd_boolean m88k_is_local_label_name PARAMS ((bfd *, const char *));
252b5132
RH
32static bfd_reloc_status_type m88k_special_reloc
33 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
34static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
35static void reloc_processing
36 PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
37
38#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
39
dc810e39
AM
40#define GET_SCNHDR_NRELOC H_GET_32
41#define GET_SCNHDR_NLNNO H_GET_32
252b5132
RH
42
43/* On coff-m88k, local labels start with '@'. */
44
45#define coff_bfd_is_local_label_name m88k_is_local_label_name
46
b34976b6 47static bfd_boolean
252b5132 48m88k_is_local_label_name (abfd, name)
5f771d47 49 bfd *abfd ATTRIBUTE_UNUSED;
252b5132
RH
50 const char *name;
51{
52 return name[0] == '@';
53}
54
b48499ec 55static bfd_reloc_status_type
252b5132
RH
56m88k_special_reloc (abfd, reloc_entry, symbol, data,
57 input_section, output_bfd, error_message)
58 bfd *abfd;
59 arelent *reloc_entry;
60 asymbol *symbol;
61 PTR data;
62 asection *input_section;
63 bfd *output_bfd;
5f771d47 64 char **error_message ATTRIBUTE_UNUSED;
252b5132
RH
65{
66 reloc_howto_type *howto = reloc_entry->howto;
67
68 switch (howto->type)
69 {
70 case R_HVRT16:
71 case R_LVRT16:
72 if (output_bfd != (bfd *) NULL)
73 {
74 /* This is a partial relocation, and we want to apply the
75 relocation to the reloc entry rather than the raw data.
76 Modify the reloc inplace to reflect what we now know. */
77
78 reloc_entry->address += input_section->output_offset;
79 }
80 else
81 {
82 bfd_vma output_base = 0;
83 bfd_vma addr = reloc_entry->address;
84 bfd_vma x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
85 asection *reloc_target_output_section;
86 long relocation = 0;
87
5c4491d3 88 /* Work out which section the relocation is targeted at and the
252b5132
RH
89 initial relocation command value. */
90
91 /* Get symbol value. (Common symbols are special.) */
92 if (bfd_is_com_section (symbol->section))
93 relocation = 0;
94 else
95 relocation = symbol->value;
96
97 reloc_target_output_section = symbol->section->output_section;
98
99 /* Convert input-section-relative symbol value to absolute. */
100 if (output_bfd)
101 output_base = 0;
102 else
103 output_base = reloc_target_output_section->vma;
104
105 relocation += output_base + symbol->section->output_offset;
106
107 /* Add in supplied addend. */
108 relocation += ((reloc_entry->addend << howto->bitsize) + x);
109
110 reloc_entry->addend = 0;
111
112 relocation >>= (bfd_vma) howto->rightshift;
113
114 /* Shift everything up to where it's going to be used */
115
116 relocation <<= (bfd_vma) howto->bitpos;
117
118 if (relocation)
dc810e39
AM
119 bfd_put_16 (abfd, (bfd_vma) relocation,
120 (unsigned char *) data + addr);
252b5132
RH
121 }
122
1049f94e 123 /* If we are not producing relocatable output, return an error if
252b5132
RH
124 the symbol is not defined. */
125 if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
126 return bfd_reloc_undefined;
127
128 return bfd_reloc_ok;
129
130 default:
131 if (output_bfd != (bfd *) NULL)
132 {
133 /* This is a partial relocation, and we want to apply the
134 relocation to the reloc entry rather than the raw data.
135 Modify the reloc inplace to reflect what we now know. */
136
137 reloc_entry->address += input_section->output_offset;
138 return bfd_reloc_ok;
139 }
140 break;
141 }
142
143 if (output_bfd == (bfd *) NULL)
144 return bfd_reloc_continue;
145
146 return bfd_reloc_ok;
147}
148
b48499ec 149static reloc_howto_type howto_table[] =
252b5132
RH
150{
151 HOWTO (R_PCR16L, /* type */
152 02, /* rightshift */
153 1, /* size (0 = byte, 1 = short, 2 = long) */
154 16, /* bitsize */
b34976b6 155 TRUE, /* pc_relative */
252b5132
RH
156 0, /* bitpos */
157 complain_overflow_signed, /* complain_on_overflow */
158 m88k_special_reloc, /* special_function */
159 "PCR16L", /* name */
b34976b6 160 FALSE, /* partial_inplace */
252b5132
RH
161 0x0000ffff, /* src_mask */
162 0x0000ffff, /* dst_mask */
b34976b6 163 TRUE), /* pcrel_offset */
252b5132
RH
164
165 HOWTO (R_PCR26L, /* type */
166 02, /* rightshift */
167 2, /* size (0 = byte, 1 = short, 2 = long) */
168 26, /* bitsize */
b34976b6 169 TRUE, /* pc_relative */
252b5132
RH
170 0, /* bitpos */
171 complain_overflow_signed, /* complain_on_overflow */
172 m88k_special_reloc, /* special_function */
173 "PCR26L", /* name */
b34976b6 174 FALSE, /* partial_inplace */
252b5132
RH
175 0x03ffffff, /* src_mask */
176 0x03ffffff, /* dst_mask */
b34976b6 177 TRUE), /* pcrel_offset */
252b5132
RH
178
179 HOWTO (R_VRT16, /* type */
180 00, /* rightshift */
181 1, /* size (0 = byte, 1 = short, 2 = long) */
182 16, /* bitsize */
b34976b6 183 FALSE, /* pc_relative */
252b5132
RH
184 0, /* bitpos */
185 complain_overflow_bitfield, /* complain_on_overflow */
186 m88k_special_reloc, /* special_function */
187 "VRT16", /* name */
b34976b6 188 FALSE, /* partial_inplace */
252b5132
RH
189 0x0000ffff, /* src_mask */
190 0x0000ffff, /* dst_mask */
b34976b6 191 TRUE), /* pcrel_offset */
252b5132
RH
192
193 HOWTO (R_HVRT16, /* type */
194 16, /* rightshift */
195 1, /* size (0 = byte, 1 = short, 2 = long) */
196 16, /* bitsize */
b34976b6 197 FALSE, /* pc_relative */
252b5132
RH
198 0, /* bitpos */
199 complain_overflow_dont, /* complain_on_overflow */
200 m88k_special_reloc, /* special_function */
201 "HVRT16", /* name */
b34976b6 202 FALSE, /* partial_inplace */
252b5132
RH
203 0x0000ffff, /* src_mask */
204 0x0000ffff, /* dst_mask */
b34976b6 205 TRUE), /* pcrel_offset */
252b5132
RH
206
207 HOWTO (R_LVRT16, /* type */
208 00, /* rightshift */
209 1, /* size (0 = byte, 1 = short, 2 = long) */
210 16, /* bitsize */
b34976b6 211 FALSE, /* pc_relative */
252b5132
RH
212 0, /* bitpos */
213 complain_overflow_dont, /* complain_on_overflow */
214 m88k_special_reloc, /* special_function */
215 "LVRT16", /* name */
b34976b6 216 FALSE, /* partial_inplace */
252b5132
RH
217 0x0000ffff, /* src_mask */
218 0x0000ffff, /* dst_mask */
b34976b6 219 TRUE), /* pcrel_offset */
252b5132
RH
220
221 HOWTO (R_VRT32, /* type */
222 00, /* rightshift */
223 2, /* size (0 = byte, 1 = short, 2 = long) */
224 32, /* bitsize */
b34976b6 225 FALSE, /* pc_relative */
252b5132
RH
226 0, /* bitpos */
227 complain_overflow_bitfield, /* complain_on_overflow */
228 m88k_special_reloc, /* special_function */
229 "VRT32", /* name */
b34976b6 230 FALSE, /* partial_inplace */
252b5132
RH
231 0xffffffff, /* src_mask */
232 0xffffffff, /* dst_mask */
b34976b6 233 TRUE), /* pcrel_offset */
252b5132
RH
234};
235
236/* Code to turn an external r_type into a pointer to an entry in the
237 above howto table. */
238static void
239rtype2howto (cache_ptr, dst)
240 arelent *cache_ptr;
241 struct internal_reloc *dst;
242{
243 if (dst->r_type >= R_PCR16L && dst->r_type <= R_VRT32)
244 {
245 cache_ptr->howto = howto_table + dst->r_type - R_PCR16L;
246 }
247 else
248 {
249 BFD_ASSERT (0);
250 }
251}
252
253#define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
254
252b5132 255/* Code to swap in the reloc offset */
dc810e39
AM
256#define SWAP_IN_RELOC_OFFSET H_GET_16
257#define SWAP_OUT_RELOC_OFFSET H_PUT_16
252b5132 258
252b5132
RH
259#define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
260 reloc_processing(relent, reloc, symbols, abfd, section)
261
262static void
263reloc_processing (relent, reloc, symbols, abfd, section)
264 arelent *relent;
265 struct internal_reloc *reloc;
266 asymbol **symbols;
267 bfd *abfd;
268 asection *section;
269{
270 relent->address = reloc->r_vaddr;
271 rtype2howto (relent, reloc);
272
273 if (((int) reloc->r_symndx) > 0)
274 {
275 relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
276 }
277 else
278 {
279 relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
280 }
281
282 relent->addend = reloc->r_offset;
283 relent->address -= section->vma;
284}
285
286#define BADMAG(x) MC88BADMAG(x)
287#include "coffcode.h"
288
289#undef coff_write_armap
290
3fa78519 291CREATE_BIG_COFF_TARGET_VEC (m88kbcs_vec, "coff-m88kbcs", 0, 0, '_', NULL, COFF_SWAP_TABLE)
This page took 0.439438 seconds and 4 git commands to generate.