1 /* BFD back-end for Motorola 88000 COFF "Binary Compatibility Standard" files.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2005, 2007, 2008, 2012 Free Software Foundation, Inc.
4 Written by Cygnus Support.
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 3 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., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
23 #define M88 1 /* Customize various include files */
27 #include "coff/m88k.h"
28 #include "coff/internal.h"
31 static bfd_reloc_status_type m88k_special_reloc
32 (bfd
*, arelent
*, asymbol
*, void *, asection
*, bfd
*, char **);
34 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
36 #define GET_SCNHDR_NRELOC H_GET_32
37 #define GET_SCNHDR_NLNNO H_GET_32
39 /* On coff-m88k, local labels start with '@'. */
41 #define coff_bfd_is_local_label_name m88k_is_local_label_name
44 m88k_is_local_label_name (bfd
*abfd ATTRIBUTE_UNUSED
, const char *name
)
46 return name
[0] == '@';
49 static bfd_reloc_status_type
50 m88k_special_reloc (bfd
*abfd
,
54 asection
*input_section
,
56 char **error_message ATTRIBUTE_UNUSED
)
58 reloc_howto_type
*howto
= reloc_entry
->howto
;
64 if (output_bfd
!= (bfd
*) NULL
)
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. */
70 reloc_entry
->address
+= input_section
->output_offset
;
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
;
80 /* Work out which section the relocation is targeted at and the
81 initial relocation command value. */
83 /* Get symbol value. (Common symbols are special.) */
84 if (bfd_is_com_section (symbol
->section
))
87 relocation
= symbol
->value
;
89 reloc_target_output_section
= symbol
->section
->output_section
;
91 /* Convert input-section-relative symbol value to absolute. */
95 output_base
= reloc_target_output_section
->vma
;
97 relocation
+= output_base
+ symbol
->section
->output_offset
;
99 /* Add in supplied addend. */
100 relocation
+= ((reloc_entry
->addend
<< howto
->bitsize
) + x
);
102 reloc_entry
->addend
= 0;
104 relocation
>>= (bfd_vma
) howto
->rightshift
;
106 /* Shift everything up to where it's going to be used */
108 relocation
<<= (bfd_vma
) howto
->bitpos
;
111 bfd_put_16 (abfd
, (bfd_vma
) relocation
,
112 (unsigned char *) data
+ addr
);
115 /* If we are not producing relocatable output, return an error if
116 the symbol is not defined. */
117 if (bfd_is_und_section (symbol
->section
) && output_bfd
== (bfd
*) NULL
)
118 return bfd_reloc_undefined
;
123 if (output_bfd
!= (bfd
*) NULL
)
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. */
129 reloc_entry
->address
+= input_section
->output_offset
;
135 if (output_bfd
== (bfd
*) NULL
)
136 return bfd_reloc_continue
;
141 static reloc_howto_type howto_table
[] =
143 HOWTO (R_PCR16L
, /* type */
145 1, /* size (0 = byte, 1 = short, 2 = long) */
147 TRUE
, /* pc_relative */
149 complain_overflow_signed
, /* complain_on_overflow */
150 m88k_special_reloc
, /* special_function */
152 FALSE
, /* partial_inplace */
153 0x0000ffff, /* src_mask */
154 0x0000ffff, /* dst_mask */
155 TRUE
), /* pcrel_offset */
157 HOWTO (R_PCR26L
, /* type */
159 2, /* size (0 = byte, 1 = short, 2 = long) */
161 TRUE
, /* pc_relative */
163 complain_overflow_signed
, /* complain_on_overflow */
164 m88k_special_reloc
, /* special_function */
166 FALSE
, /* partial_inplace */
167 0x03ffffff, /* src_mask */
168 0x03ffffff, /* dst_mask */
169 TRUE
), /* pcrel_offset */
171 HOWTO (R_VRT16
, /* type */
173 1, /* size (0 = byte, 1 = short, 2 = long) */
175 FALSE
, /* pc_relative */
177 complain_overflow_bitfield
, /* complain_on_overflow */
178 m88k_special_reloc
, /* special_function */
180 FALSE
, /* partial_inplace */
181 0x0000ffff, /* src_mask */
182 0x0000ffff, /* dst_mask */
183 TRUE
), /* pcrel_offset */
185 HOWTO (R_HVRT16
, /* type */
187 1, /* size (0 = byte, 1 = short, 2 = long) */
189 FALSE
, /* pc_relative */
191 complain_overflow_dont
, /* complain_on_overflow */
192 m88k_special_reloc
, /* special_function */
194 FALSE
, /* partial_inplace */
195 0x0000ffff, /* src_mask */
196 0x0000ffff, /* dst_mask */
197 TRUE
), /* pcrel_offset */
199 HOWTO (R_LVRT16
, /* type */
201 1, /* size (0 = byte, 1 = short, 2 = long) */
203 FALSE
, /* pc_relative */
205 complain_overflow_dont
, /* complain_on_overflow */
206 m88k_special_reloc
, /* special_function */
208 FALSE
, /* partial_inplace */
209 0x0000ffff, /* src_mask */
210 0x0000ffff, /* dst_mask */
211 TRUE
), /* pcrel_offset */
213 HOWTO (R_VRT32
, /* type */
215 2, /* size (0 = byte, 1 = short, 2 = long) */
217 FALSE
, /* pc_relative */
219 complain_overflow_bitfield
, /* complain_on_overflow */
220 m88k_special_reloc
, /* special_function */
222 FALSE
, /* partial_inplace */
223 0xffffffff, /* src_mask */
224 0xffffffff, /* dst_mask */
225 TRUE
), /* pcrel_offset */
228 /* Code to turn an external r_type into a pointer to an entry in the
229 above howto table. */
231 rtype2howto (arelent
*cache_ptr
, struct internal_reloc
*dst
)
233 if (dst
->r_type
>= R_PCR16L
&& dst
->r_type
<= R_VRT32
)
235 cache_ptr
->howto
= howto_table
+ dst
->r_type
- R_PCR16L
;
243 #define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
245 /* Code to swap in the reloc offset */
246 #define SWAP_IN_RELOC_OFFSET H_GET_16
247 #define SWAP_OUT_RELOC_OFFSET H_PUT_16
249 #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
250 reloc_processing(relent, reloc, symbols, abfd, section)
253 reloc_processing (arelent
*relent
,
254 struct internal_reloc
*reloc
,
259 relent
->address
= reloc
->r_vaddr
;
260 rtype2howto (relent
, reloc
);
262 if (((int) reloc
->r_symndx
) > 0)
264 relent
->sym_ptr_ptr
= symbols
+ obj_convert (abfd
)[reloc
->r_symndx
];
268 relent
->sym_ptr_ptr
= bfd_abs_section_ptr
->symbol_ptr_ptr
;
271 relent
->addend
= reloc
->r_offset
;
272 relent
->address
-= section
->vma
;
275 #define BADMAG(x) MC88BADMAG(x)
277 #ifndef bfd_pe_print_pdata
278 #define bfd_pe_print_pdata NULL
281 #include "coffcode.h"
283 #undef coff_write_armap
285 CREATE_BIG_COFF_TARGET_VEC (m88kbcs_vec
, "coff-m88kbcs", 0, 0, '_', NULL
, COFF_SWAP_TABLE
)