source: trunk/src/binutils/bfd/coff-m88k.c@ 610

Last change on this file since 610 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 8.3 KB
Line 
1/* BFD back-end for Motorola 88000 COFF "Binary Compatability Standard" files.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002
4 Free Software Foundation, Inc.
5 Written by Cygnus Support.
6
7This file is part of BFD, the Binary File Descriptor library.
8
9This program is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 2 of the License, or
12(at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17GNU General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with this program; if not, write to the Free Software
21Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23#define M88 1 /* Customize various include files */
24#include "bfd.h"
25#include "sysdep.h"
26#include "libbfd.h"
27#include "coff/m88k.h"
28#include "coff/internal.h"
29#include "libcoff.h"
30
31static bfd_boolean m88k_is_local_label_name PARAMS ((bfd *, const char *));
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
40#define GET_SCNHDR_NRELOC H_GET_32
41#define GET_SCNHDR_NLNNO H_GET_32
42
43/* On coff-m88k, local labels start with '@'. */
44
45#define coff_bfd_is_local_label_name m88k_is_local_label_name
46
47static bfd_boolean
48m88k_is_local_label_name (abfd, name)
49 bfd *abfd ATTRIBUTE_UNUSED;
50 const char *name;
51{
52 return name[0] == '@';
53}
54
55static bfd_reloc_status_type
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;
64 char **error_message ATTRIBUTE_UNUSED;
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
88 /* Work out which section the relocation is targetted at and the
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)
119 bfd_put_16 (abfd, (bfd_vma) relocation,
120 (unsigned char *) data + addr);
121 }
122
123 /* If we are not producing relocateable output, return an error if
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
149static reloc_howto_type howto_table[] =
150{
151 HOWTO (R_PCR16L, /* type */
152 02, /* rightshift */
153 1, /* size (0 = byte, 1 = short, 2 = long) */
154 16, /* bitsize */
155 TRUE, /* pc_relative */
156 0, /* bitpos */
157 complain_overflow_signed, /* complain_on_overflow */
158 m88k_special_reloc, /* special_function */
159 "PCR16L", /* name */
160 FALSE, /* partial_inplace */
161 0x0000ffff, /* src_mask */
162 0x0000ffff, /* dst_mask */
163 TRUE), /* pcrel_offset */
164
165 HOWTO (R_PCR26L, /* type */
166 02, /* rightshift */
167 2, /* size (0 = byte, 1 = short, 2 = long) */
168 26, /* bitsize */
169 TRUE, /* pc_relative */
170 0, /* bitpos */
171 complain_overflow_signed, /* complain_on_overflow */
172 m88k_special_reloc, /* special_function */
173 "PCR26L", /* name */
174 FALSE, /* partial_inplace */
175 0x03ffffff, /* src_mask */
176 0x03ffffff, /* dst_mask */
177 TRUE), /* pcrel_offset */
178
179 HOWTO (R_VRT16, /* type */
180 00, /* rightshift */
181 1, /* size (0 = byte, 1 = short, 2 = long) */
182 16, /* bitsize */
183 FALSE, /* pc_relative */
184 0, /* bitpos */
185 complain_overflow_bitfield, /* complain_on_overflow */
186 m88k_special_reloc, /* special_function */
187 "VRT16", /* name */
188 FALSE, /* partial_inplace */
189 0x0000ffff, /* src_mask */
190 0x0000ffff, /* dst_mask */
191 TRUE), /* pcrel_offset */
192
193 HOWTO (R_HVRT16, /* type */
194 16, /* rightshift */
195 1, /* size (0 = byte, 1 = short, 2 = long) */
196 16, /* bitsize */
197 FALSE, /* pc_relative */
198 0, /* bitpos */
199 complain_overflow_dont, /* complain_on_overflow */
200 m88k_special_reloc, /* special_function */
201 "HVRT16", /* name */
202 FALSE, /* partial_inplace */
203 0x0000ffff, /* src_mask */
204 0x0000ffff, /* dst_mask */
205 TRUE), /* pcrel_offset */
206
207 HOWTO (R_LVRT16, /* type */
208 00, /* rightshift */
209 1, /* size (0 = byte, 1 = short, 2 = long) */
210 16, /* bitsize */
211 FALSE, /* pc_relative */
212 0, /* bitpos */
213 complain_overflow_dont, /* complain_on_overflow */
214 m88k_special_reloc, /* special_function */
215 "LVRT16", /* name */
216 FALSE, /* partial_inplace */
217 0x0000ffff, /* src_mask */
218 0x0000ffff, /* dst_mask */
219 TRUE), /* pcrel_offset */
220
221 HOWTO (R_VRT32, /* type */
222 00, /* rightshift */
223 2, /* size (0 = byte, 1 = short, 2 = long) */
224 32, /* bitsize */
225 FALSE, /* pc_relative */
226 0, /* bitpos */
227 complain_overflow_bitfield, /* complain_on_overflow */
228 m88k_special_reloc, /* special_function */
229 "VRT32", /* name */
230 FALSE, /* partial_inplace */
231 0xffffffff, /* src_mask */
232 0xffffffff, /* dst_mask */
233 TRUE), /* pcrel_offset */
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
255/* Code to swap in the reloc offset */
256#define SWAP_IN_RELOC_OFFSET H_GET_16
257#define SWAP_OUT_RELOC_OFFSET H_PUT_16
258
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
291CREATE_BIG_COFF_TARGET_VEC (m88kbcs_vec, "coff-m88kbcs", 0, 0, '_', NULL)
Note: See TracBrowser for help on using the repository browser.