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