1*3d8817e4Smiod /* BFD back-end for MAXQ COFF binaries.
2*3d8817e4Smiod Copyright 2004 Free Software Foundation, Inc.
3*3d8817e4Smiod
4*3d8817e4Smiod Contributed by Vineet Sharma (vineets@noida.hcltech.com) Inderpreet S.
5*3d8817e4Smiod (inderpreetb@noida.hcltech.com)
6*3d8817e4Smiod
7*3d8817e4Smiod HCL Technologies Ltd.
8*3d8817e4Smiod
9*3d8817e4Smiod This file is part of BFD, the Binary File Descriptor library.
10*3d8817e4Smiod
11*3d8817e4Smiod This program is free software; you can redistribute it and/or modify it
12*3d8817e4Smiod under the terms of the GNU General Public License as published by the Free
13*3d8817e4Smiod Software Foundation; either version 2 of the License, or (at your option)
14*3d8817e4Smiod any later version.
15*3d8817e4Smiod
16*3d8817e4Smiod This program is distributed in the hope that it will be useful, but
17*3d8817e4Smiod WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18*3d8817e4Smiod or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19*3d8817e4Smiod for more details.
20*3d8817e4Smiod
21*3d8817e4Smiod You should have received a copy of the GNU General Public License along
22*3d8817e4Smiod with this program; if not, write to the Free Software Foundation, Inc.,
23*3d8817e4Smiod 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
24*3d8817e4Smiod
25*3d8817e4Smiod #include "bfd.h"
26*3d8817e4Smiod #include "sysdep.h"
27*3d8817e4Smiod #include "libbfd.h"
28*3d8817e4Smiod #include "coff/maxq.h"
29*3d8817e4Smiod #include "coff/internal.h"
30*3d8817e4Smiod #include "libcoff.h"
31*3d8817e4Smiod #include "libiberty.h"
32*3d8817e4Smiod
33*3d8817e4Smiod #ifndef MAXQ20
34*3d8817e4Smiod #define MAXQ20 1
35*3d8817e4Smiod #endif
36*3d8817e4Smiod
37*3d8817e4Smiod #define RTYPE2HOWTO(cache_ptr, dst) \
38*3d8817e4Smiod ((cache_ptr)->howto = \
39*3d8817e4Smiod ((dst)->r_type < 48 \
40*3d8817e4Smiod ? howto_table + (((dst)->r_type==47) ? 6: ((dst)->r_type)) \
41*3d8817e4Smiod : NULL))
42*3d8817e4Smiod
43*3d8817e4Smiod #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
44*3d8817e4Smiod
45*3d8817e4Smiod /* Code to swap in the reloc offset. */
46*3d8817e4Smiod #define SWAP_IN_RELOC_OFFSET H_GET_16
47*3d8817e4Smiod #define SWAP_OUT_RELOC_OFFSET H_PUT_16
48*3d8817e4Smiod
49*3d8817e4Smiod #define SHORT_JUMP BFD_RELOC_16_PCREL_S2
50*3d8817e4Smiod #define LONG_JUMP BFD_RELOC_14
51*3d8817e4Smiod #define ABSOLUTE_ADDR_FOR_DATA BFD_RELOC_24
52*3d8817e4Smiod
53*3d8817e4Smiod /* checks the range of short jump -127 to 128 */
54*3d8817e4Smiod #define IS_SJUMP_RANGE(x) ((x > -128) && (x < 129))
55*3d8817e4Smiod #define HIGH_WORD_MASK 0xff00
56*3d8817e4Smiod #define LOW_WORD_MASK 0x00ff
57*3d8817e4Smiod
58*3d8817e4Smiod static long
get_symbol_value(asymbol * symbol)59*3d8817e4Smiod get_symbol_value (asymbol *symbol)
60*3d8817e4Smiod {
61*3d8817e4Smiod long relocation = 0;
62*3d8817e4Smiod
63*3d8817e4Smiod if (bfd_is_com_section (symbol->section))
64*3d8817e4Smiod relocation = 0;
65*3d8817e4Smiod else
66*3d8817e4Smiod relocation = symbol->value +
67*3d8817e4Smiod symbol->section->output_section->vma + symbol->section->output_offset;
68*3d8817e4Smiod
69*3d8817e4Smiod return relocation;
70*3d8817e4Smiod }
71*3d8817e4Smiod
72*3d8817e4Smiod /* This function performs all the maxq relocations.
73*3d8817e4Smiod FIXME: The handling of the addend in the 'BFD_*'
74*3d8817e4Smiod relocations types. */
75*3d8817e4Smiod
76*3d8817e4Smiod static bfd_reloc_status_type
coff_maxq20_reloc(bfd * abfd,arelent * reloc_entry,asymbol * symbol_in,void * data,asection * input_section ATTRIBUTE_UNUSED,bfd * output_bfd ATTRIBUTE_UNUSED,char ** error_message ATTRIBUTE_UNUSED)77*3d8817e4Smiod coff_maxq20_reloc (bfd * abfd,
78*3d8817e4Smiod arelent * reloc_entry,
79*3d8817e4Smiod asymbol * symbol_in,
80*3d8817e4Smiod void * data,
81*3d8817e4Smiod asection * input_section ATTRIBUTE_UNUSED,
82*3d8817e4Smiod bfd * output_bfd ATTRIBUTE_UNUSED,
83*3d8817e4Smiod char ** error_message ATTRIBUTE_UNUSED)
84*3d8817e4Smiod {
85*3d8817e4Smiod reloc_howto_type *howto = NULL;
86*3d8817e4Smiod unsigned char *addr = NULL;
87*3d8817e4Smiod unsigned long x = 0;
88*3d8817e4Smiod long call_addr = 0;
89*3d8817e4Smiod short addend = 0;
90*3d8817e4Smiod long diff = 0;
91*3d8817e4Smiod
92*3d8817e4Smiod /* If this is an undefined symbol, return error. */
93*3d8817e4Smiod if (symbol_in->section == &bfd_und_section
94*3d8817e4Smiod && (symbol_in->flags & BSF_WEAK) == 0)
95*3d8817e4Smiod return bfd_reloc_continue;
96*3d8817e4Smiod
97*3d8817e4Smiod if (data && reloc_entry)
98*3d8817e4Smiod {
99*3d8817e4Smiod howto = reloc_entry->howto;
100*3d8817e4Smiod addr = (unsigned char *) data + reloc_entry->address;
101*3d8817e4Smiod call_addr = call_addr - call_addr;
102*3d8817e4Smiod call_addr = get_symbol_value (symbol_in);
103*3d8817e4Smiod
104*3d8817e4Smiod /* Over here the value val stores the 8 bit/16 bit value. We will put a
105*3d8817e4Smiod check if we are moving a 16 bit immediate value into an 8 bit
106*3d8817e4Smiod register. In that case we will generate a Upper bytes into PFX[0]
107*3d8817e4Smiod and move the lower 8 bits as SRC. */
108*3d8817e4Smiod
109*3d8817e4Smiod switch (reloc_entry->howto->type)
110*3d8817e4Smiod {
111*3d8817e4Smiod /* BFD_RELOC_16_PCREL_S2 47 Handles all the relative jumps and
112*3d8817e4Smiod calls Note: Every relative jump or call is in words. */
113*3d8817e4Smiod case SHORT_JUMP:
114*3d8817e4Smiod /* Handle any addend. */
115*3d8817e4Smiod addend = reloc_entry->addend;
116*3d8817e4Smiod
117*3d8817e4Smiod if (addend > call_addr || addend > 0)
118*3d8817e4Smiod call_addr = symbol_in->section->output_section->vma + addend;
119*3d8817e4Smiod else if (addend < call_addr && addend > 0)
120*3d8817e4Smiod call_addr = call_addr + addend;
121*3d8817e4Smiod else if (addend < 0)
122*3d8817e4Smiod call_addr = call_addr + addend;
123*3d8817e4Smiod
124*3d8817e4Smiod diff = ((call_addr << 1) - (reloc_entry->address << 1));
125*3d8817e4Smiod
126*3d8817e4Smiod if (!IS_SJUMP_RANGE (diff))
127*3d8817e4Smiod {
128*3d8817e4Smiod bfd_perror (_("Can't Make it a Short Jump"));
129*3d8817e4Smiod return bfd_reloc_outofrange;
130*3d8817e4Smiod }
131*3d8817e4Smiod
132*3d8817e4Smiod x = bfd_get_16 (abfd, addr);
133*3d8817e4Smiod
134*3d8817e4Smiod x = x & LOW_WORD_MASK;
135*3d8817e4Smiod x = x | (diff << 8);
136*3d8817e4Smiod bfd_put_16 (abfd, (bfd_vma) x, addr);
137*3d8817e4Smiod
138*3d8817e4Smiod return bfd_reloc_ok;
139*3d8817e4Smiod
140*3d8817e4Smiod case ABSOLUTE_ADDR_FOR_DATA:
141*3d8817e4Smiod case LONG_JUMP:
142*3d8817e4Smiod /* BFD_RELOC_14 Handles intersegment or long jumps which might be
143*3d8817e4Smiod from code to code or code to data segment jumps. Note: When this
144*3d8817e4Smiod fucntion is called by gas the section flags somehow do not
145*3d8817e4Smiod contain the info about the section type(CODE or DATA). Thus the
146*3d8817e4Smiod user needs to evoke the linker after assembling the files
147*3d8817e4Smiod because the Code-Code relocs are word aligned but code-data are
148*3d8817e4Smiod byte aligned. */
149*3d8817e4Smiod addend = (reloc_entry->addend - reloc_entry->addend);
150*3d8817e4Smiod
151*3d8817e4Smiod /* Handle any addend. */
152*3d8817e4Smiod addend = reloc_entry->addend;
153*3d8817e4Smiod
154*3d8817e4Smiod /* For relocation involving multiple file added becomes zero thus
155*3d8817e4Smiod this fails - check for zero added. In another case when we try
156*3d8817e4Smiod to add a stub to a file the addend shows the offset from the
157*3d8817e4Smiod start od this file. */
158*3d8817e4Smiod addend = 0;
159*3d8817e4Smiod
160*3d8817e4Smiod if (!bfd_is_com_section (symbol_in->section) &&
161*3d8817e4Smiod ((symbol_in->flags & BSF_OLD_COMMON) == 0))
162*3d8817e4Smiod {
163*3d8817e4Smiod if (reloc_entry->addend > symbol_in->value)
164*3d8817e4Smiod addend = reloc_entry->addend - symbol_in->value;
165*3d8817e4Smiod
166*3d8817e4Smiod if ((reloc_entry->addend < symbol_in->value)
167*3d8817e4Smiod && (reloc_entry->addend != 0))
168*3d8817e4Smiod addend = reloc_entry->addend - symbol_in->value;
169*3d8817e4Smiod
170*3d8817e4Smiod if (reloc_entry->addend == symbol_in->value)
171*3d8817e4Smiod addend = 0;
172*3d8817e4Smiod }
173*3d8817e4Smiod
174*3d8817e4Smiod if (bfd_is_com_section (symbol_in->section) ||
175*3d8817e4Smiod ((symbol_in->flags & BSF_OLD_COMMON) != 0))
176*3d8817e4Smiod addend = reloc_entry->addend;
177*3d8817e4Smiod
178*3d8817e4Smiod if (addend < 0
179*3d8817e4Smiod && (call_addr < (long) (addend * (-1))))
180*3d8817e4Smiod addend = 0;
181*3d8817e4Smiod
182*3d8817e4Smiod call_addr += addend;
183*3d8817e4Smiod
184*3d8817e4Smiod /* FIXME: This check does not work well with the assembler,
185*3d8817e4Smiod linker needs to be run always. */
186*3d8817e4Smiod if ((symbol_in->section->flags & SEC_CODE) == SEC_CODE)
187*3d8817e4Smiod {
188*3d8817e4Smiod /* Convert it into words. */
189*3d8817e4Smiod call_addr = call_addr >> 1;
190*3d8817e4Smiod
191*3d8817e4Smiod if (call_addr > 0xFFFF) /* Intersegment Jump. */
192*3d8817e4Smiod {
193*3d8817e4Smiod bfd_perror (_("Exceeds Long Jump Range"));
194*3d8817e4Smiod return bfd_reloc_outofrange;
195*3d8817e4Smiod }
196*3d8817e4Smiod }
197*3d8817e4Smiod else
198*3d8817e4Smiod {
199*3d8817e4Smiod /* case ABSOLUTE_ADDR_FOR_DATA : Resolves any code-data
200*3d8817e4Smiod segemnt relocs. These are NOT word aligned. */
201*3d8817e4Smiod
202*3d8817e4Smiod if (call_addr > 0xFFFF) /* Intersegment Jump. */
203*3d8817e4Smiod {
204*3d8817e4Smiod bfd_perror (_("Absolute address Exceeds 16 bit Range"));
205*3d8817e4Smiod return bfd_reloc_outofrange;
206*3d8817e4Smiod }
207*3d8817e4Smiod }
208*3d8817e4Smiod
209*3d8817e4Smiod x = bfd_get_32 (abfd, addr);
210*3d8817e4Smiod
211*3d8817e4Smiod x = (x & 0xFF00FF00);
212*3d8817e4Smiod x = (x | ((call_addr & HIGH_WORD_MASK) >> 8));
213*3d8817e4Smiod x = (x | (call_addr & LOW_WORD_MASK) << 16);
214*3d8817e4Smiod
215*3d8817e4Smiod bfd_put_32 (abfd, (bfd_vma) x, addr);
216*3d8817e4Smiod return bfd_reloc_ok;
217*3d8817e4Smiod
218*3d8817e4Smiod case BFD_RELOC_8:
219*3d8817e4Smiod addend = (reloc_entry->addend - reloc_entry->addend);
220*3d8817e4Smiod
221*3d8817e4Smiod if (!bfd_is_com_section (symbol_in->section) &&
222*3d8817e4Smiod ((symbol_in->flags & BSF_OLD_COMMON) == 0))
223*3d8817e4Smiod {
224*3d8817e4Smiod if (reloc_entry->addend > symbol_in->value)
225*3d8817e4Smiod addend = reloc_entry->addend - symbol_in->value;
226*3d8817e4Smiod if (reloc_entry->addend < symbol_in->value)
227*3d8817e4Smiod addend = reloc_entry->addend - symbol_in->value;
228*3d8817e4Smiod if (reloc_entry->addend == symbol_in->value)
229*3d8817e4Smiod addend = 0;
230*3d8817e4Smiod }
231*3d8817e4Smiod
232*3d8817e4Smiod if (bfd_is_com_section (symbol_in->section) ||
233*3d8817e4Smiod ((symbol_in->flags & BSF_OLD_COMMON) != 0))
234*3d8817e4Smiod addend = reloc_entry->addend;
235*3d8817e4Smiod
236*3d8817e4Smiod if (addend < 0
237*3d8817e4Smiod && (call_addr < (long) (addend * (-1))))
238*3d8817e4Smiod addend = 0;
239*3d8817e4Smiod
240*3d8817e4Smiod if (call_addr + addend > 0xFF)
241*3d8817e4Smiod {
242*3d8817e4Smiod bfd_perror (_("Absolute address Exceeds 8 bit Range"));
243*3d8817e4Smiod return bfd_reloc_outofrange;
244*3d8817e4Smiod }
245*3d8817e4Smiod
246*3d8817e4Smiod x = bfd_get_8 (abfd, addr);
247*3d8817e4Smiod x = x & 0x00;
248*3d8817e4Smiod x = x | (call_addr + addend);
249*3d8817e4Smiod
250*3d8817e4Smiod bfd_put_8 (abfd, (bfd_vma) x, addr);
251*3d8817e4Smiod return bfd_reloc_ok;
252*3d8817e4Smiod
253*3d8817e4Smiod case BFD_RELOC_16:
254*3d8817e4Smiod addend = (reloc_entry->addend - reloc_entry->addend);
255*3d8817e4Smiod if (!bfd_is_com_section (symbol_in->section) &&
256*3d8817e4Smiod ((symbol_in->flags & BSF_OLD_COMMON) == 0))
257*3d8817e4Smiod {
258*3d8817e4Smiod if (reloc_entry->addend > symbol_in->value)
259*3d8817e4Smiod addend = reloc_entry->addend - symbol_in->value;
260*3d8817e4Smiod
261*3d8817e4Smiod if (reloc_entry->addend < symbol_in->value)
262*3d8817e4Smiod addend = reloc_entry->addend - symbol_in->value;
263*3d8817e4Smiod
264*3d8817e4Smiod if (reloc_entry->addend == symbol_in->value)
265*3d8817e4Smiod addend = 0;
266*3d8817e4Smiod }
267*3d8817e4Smiod
268*3d8817e4Smiod if (bfd_is_com_section (symbol_in->section) ||
269*3d8817e4Smiod ((symbol_in->flags & BSF_OLD_COMMON) != 0))
270*3d8817e4Smiod addend = reloc_entry->addend;
271*3d8817e4Smiod
272*3d8817e4Smiod if (addend < 0
273*3d8817e4Smiod && (call_addr < (long) (addend * (-1))))
274*3d8817e4Smiod addend = 0;
275*3d8817e4Smiod
276*3d8817e4Smiod if ((call_addr + addend) > 0xFFFF)
277*3d8817e4Smiod {
278*3d8817e4Smiod bfd_perror (_("Absolute address Exceeds 16 bit Range"));
279*3d8817e4Smiod return bfd_reloc_outofrange;
280*3d8817e4Smiod }
281*3d8817e4Smiod else
282*3d8817e4Smiod {
283*3d8817e4Smiod unsigned short val = (call_addr + addend);
284*3d8817e4Smiod
285*3d8817e4Smiod x = bfd_get_16 (abfd, addr);
286*3d8817e4Smiod
287*3d8817e4Smiod /* LE */
288*3d8817e4Smiod x = (x & 0x0000); /* Flush garbage value. */
289*3d8817e4Smiod x = val;
290*3d8817e4Smiod if ((symbol_in->section->flags & SEC_CODE) == SEC_CODE)
291*3d8817e4Smiod x = x >> 1; /* Convert it into words. */
292*3d8817e4Smiod }
293*3d8817e4Smiod
294*3d8817e4Smiod bfd_put_16 (abfd, (bfd_vma) x, addr);
295*3d8817e4Smiod return bfd_reloc_ok;
296*3d8817e4Smiod
297*3d8817e4Smiod case BFD_RELOC_32:
298*3d8817e4Smiod addend = (reloc_entry->addend - reloc_entry->addend);
299*3d8817e4Smiod
300*3d8817e4Smiod if (!bfd_is_com_section (symbol_in->section) &&
301*3d8817e4Smiod ((symbol_in->flags & BSF_OLD_COMMON) == 0))
302*3d8817e4Smiod {
303*3d8817e4Smiod if (reloc_entry->addend > symbol_in->value)
304*3d8817e4Smiod addend = reloc_entry->addend - symbol_in->value;
305*3d8817e4Smiod if (reloc_entry->addend < symbol_in->value)
306*3d8817e4Smiod addend = reloc_entry->addend - symbol_in->value;
307*3d8817e4Smiod if (reloc_entry->addend == symbol_in->value)
308*3d8817e4Smiod addend = 0;
309*3d8817e4Smiod }
310*3d8817e4Smiod
311*3d8817e4Smiod if (bfd_is_com_section (symbol_in->section) ||
312*3d8817e4Smiod ((symbol_in->flags & BSF_OLD_COMMON) != 0))
313*3d8817e4Smiod addend = reloc_entry->addend;
314*3d8817e4Smiod
315*3d8817e4Smiod if (addend < 0
316*3d8817e4Smiod && (call_addr < (long) (addend * (-1))))
317*3d8817e4Smiod addend = 0;
318*3d8817e4Smiod
319*3d8817e4Smiod if ((call_addr + addend) < 0)
320*3d8817e4Smiod {
321*3d8817e4Smiod bfd_perror ("Absolute address Exceeds 32 bit Range");
322*3d8817e4Smiod return bfd_reloc_outofrange;
323*3d8817e4Smiod }
324*3d8817e4Smiod
325*3d8817e4Smiod x = bfd_get_32 (abfd, addr);
326*3d8817e4Smiod x = (x & 0x0000); /* Flush garbage value. */
327*3d8817e4Smiod x = call_addr + addend;
328*3d8817e4Smiod if ((symbol_in->section->flags & SEC_CODE) == SEC_CODE)
329*3d8817e4Smiod x = x >> 1; /* Convert it into words. */
330*3d8817e4Smiod
331*3d8817e4Smiod bfd_put_32 (abfd, (bfd_vma) x, addr);
332*3d8817e4Smiod return bfd_reloc_ok;
333*3d8817e4Smiod
334*3d8817e4Smiod default:
335*3d8817e4Smiod bfd_perror (_("Unrecognized Reloc Type"));
336*3d8817e4Smiod return bfd_reloc_notsupported;
337*3d8817e4Smiod }
338*3d8817e4Smiod }
339*3d8817e4Smiod
340*3d8817e4Smiod return bfd_reloc_notsupported;
341*3d8817e4Smiod }
342*3d8817e4Smiod
343*3d8817e4Smiod static reloc_howto_type howto_table[] =
344*3d8817e4Smiod {
345*3d8817e4Smiod EMPTY_HOWTO (0),
346*3d8817e4Smiod EMPTY_HOWTO (1),
347*3d8817e4Smiod {
348*3d8817e4Smiod BFD_RELOC_32, 0, 1, 8, FALSE, 0, complain_overflow_bitfield,
349*3d8817e4Smiod coff_maxq20_reloc, "32Bit", TRUE, 0x000000ff, 0x000000ff, TRUE
350*3d8817e4Smiod },
351*3d8817e4Smiod {
352*3d8817e4Smiod SHORT_JUMP, 0, 1, 8, FALSE, 0, complain_overflow_bitfield,
353*3d8817e4Smiod coff_maxq20_reloc, "SHORT_JMP", TRUE, 0x000000ff, 0x000000ff, TRUE
354*3d8817e4Smiod },
355*3d8817e4Smiod {
356*3d8817e4Smiod ABSOLUTE_ADDR_FOR_DATA, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
357*3d8817e4Smiod coff_maxq20_reloc, "INTERSEGMENT_RELOC", TRUE, 0x00000000, 0x00000000,
358*3d8817e4Smiod FALSE
359*3d8817e4Smiod },
360*3d8817e4Smiod {
361*3d8817e4Smiod BFD_RELOC_16, 0, 1, 8, FALSE, 0, complain_overflow_bitfield,
362*3d8817e4Smiod coff_maxq20_reloc, "16Bit", TRUE, 0x000000ff, 0x000000ff, TRUE
363*3d8817e4Smiod },
364*3d8817e4Smiod {
365*3d8817e4Smiod LONG_JUMP, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
366*3d8817e4Smiod coff_maxq20_reloc, "LONG_JUMP", TRUE, 0x00000000, 0x00000000, FALSE
367*3d8817e4Smiod },
368*3d8817e4Smiod {
369*3d8817e4Smiod BFD_RELOC_8, 0, 1, 8, FALSE, 0, complain_overflow_bitfield,
370*3d8817e4Smiod coff_maxq20_reloc, "8bit", TRUE, 0x000000ff, 0x000000ff, TRUE
371*3d8817e4Smiod },
372*3d8817e4Smiod EMPTY_HOWTO (8),
373*3d8817e4Smiod EMPTY_HOWTO (9),
374*3d8817e4Smiod EMPTY_HOWTO (10),
375*3d8817e4Smiod };
376*3d8817e4Smiod
377*3d8817e4Smiod /* Map BFD reloc types to MAXQ COFF reloc types. */
378*3d8817e4Smiod
379*3d8817e4Smiod typedef struct maxq_reloc_map
380*3d8817e4Smiod {
381*3d8817e4Smiod bfd_reloc_code_real_type bfd_reloc_val;
382*3d8817e4Smiod unsigned int maxq_reloc_val;
383*3d8817e4Smiod reloc_howto_type * table;
384*3d8817e4Smiod }
385*3d8817e4Smiod reloc_map;
386*3d8817e4Smiod
387*3d8817e4Smiod static const reloc_map maxq_reloc_map[] =
388*3d8817e4Smiod {
389*3d8817e4Smiod {BFD_RELOC_16_PCREL_S2, SHORT_JUMP, howto_table},
390*3d8817e4Smiod {BFD_RELOC_16, LONG_JUMP, howto_table},
391*3d8817e4Smiod };
392*3d8817e4Smiod
393*3d8817e4Smiod static reloc_howto_type *
maxq_reloc_type_lookup(bfd * abfd ATTRIBUTE_UNUSED,bfd_reloc_code_real_type code)394*3d8817e4Smiod maxq_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
395*3d8817e4Smiod bfd_reloc_code_real_type code)
396*3d8817e4Smiod {
397*3d8817e4Smiod unsigned int i;
398*3d8817e4Smiod
399*3d8817e4Smiod for (i = 0; i < ARRAY_SIZE (maxq_reloc_map); i++)
400*3d8817e4Smiod {
401*3d8817e4Smiod const reloc_map *entry;
402*3d8817e4Smiod
403*3d8817e4Smiod entry = maxq_reloc_map + i;
404*3d8817e4Smiod
405*3d8817e4Smiod switch (code)
406*3d8817e4Smiod {
407*3d8817e4Smiod /* SHORT JUMP */
408*3d8817e4Smiod case BFD_RELOC_16_PCREL_S2:
409*3d8817e4Smiod return howto_table + 3;
410*3d8817e4Smiod
411*3d8817e4Smiod /* INTERSEGMENT JUMP */
412*3d8817e4Smiod case BFD_RELOC_24:
413*3d8817e4Smiod return howto_table + 4;
414*3d8817e4Smiod
415*3d8817e4Smiod /* BYTE RELOC */
416*3d8817e4Smiod case BFD_RELOC_8:
417*3d8817e4Smiod return howto_table + 7;
418*3d8817e4Smiod
419*3d8817e4Smiod /* WORD RELOC */
420*3d8817e4Smiod case BFD_RELOC_16:
421*3d8817e4Smiod return howto_table + 5;
422*3d8817e4Smiod
423*3d8817e4Smiod /* LONG RELOC */
424*3d8817e4Smiod case BFD_RELOC_32:
425*3d8817e4Smiod return howto_table + 2;
426*3d8817e4Smiod
427*3d8817e4Smiod /* LONG JUMP */
428*3d8817e4Smiod case BFD_RELOC_14:
429*3d8817e4Smiod return howto_table + 6;
430*3d8817e4Smiod
431*3d8817e4Smiod default:
432*3d8817e4Smiod return NULL;
433*3d8817e4Smiod }
434*3d8817e4Smiod }
435*3d8817e4Smiod
436*3d8817e4Smiod return NULL;
437*3d8817e4Smiod }
438*3d8817e4Smiod
439*3d8817e4Smiod #define coff_bfd_reloc_type_lookup maxq_reloc_type_lookup
440*3d8817e4Smiod
441*3d8817e4Smiod /* Perform any necessary magic to the addend in a reloc entry. */
442*3d8817e4Smiod #define CALC_ADDEND(abfd, symbol, ext_reloc, cache_ptr) \
443*3d8817e4Smiod cache_ptr->addend = ext_reloc.r_offset;
444*3d8817e4Smiod
445*3d8817e4Smiod #include "coffcode.h"
446*3d8817e4Smiod
447*3d8817e4Smiod #ifndef TARGET_UNDERSCORE
448*3d8817e4Smiod #define TARGET_UNDERSCORE 1
449*3d8817e4Smiod #endif
450*3d8817e4Smiod
451*3d8817e4Smiod #ifndef EXTRA_S_FLAGS
452*3d8817e4Smiod #define EXTRA_S_FLAGS 0
453*3d8817e4Smiod #endif
454*3d8817e4Smiod
455*3d8817e4Smiod /* Forward declaration for use initialising alternative_target field. */
456*3d8817e4Smiod CREATE_LITTLE_COFF_TARGET_VEC (maxqcoff_vec, "coff-maxq", 0, EXTRA_S_FLAGS,
457*3d8817e4Smiod TARGET_UNDERSCORE, NULL, COFF_SWAP_TABLE);
458*3d8817e4Smiod
459