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