OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [bfd/] [elf32-frv.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* FRV-specific support for 32-bit ELF.
2
   Copyright (C) 2002 Free Software Foundation, Inc.
3
 
4
This file is part of BFD, the Binary File Descriptor library.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
 
20
#include "bfd.h"
21
#include "sysdep.h"
22
#include "libbfd.h"
23
#include "elf-bfd.h"
24
#include "elf/frv.h"
25
 
26
/* Forward declarations.  */
27
static bfd_reloc_status_type elf32_frv_relocate_lo16
28
  PARAMS ((bfd *,  Elf_Internal_Rela *, bfd_byte *, bfd_vma));
29
static bfd_reloc_status_type elf32_frv_relocate_hi16
30
  PARAMS ((bfd *,  Elf_Internal_Rela *, bfd_byte *, bfd_vma));
31
static bfd_reloc_status_type elf32_frv_relocate_label24
32
  PARAMS ((bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
33
static bfd_reloc_status_type elf32_frv_relocate_gprel12
34
  PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
35
static bfd_reloc_status_type elf32_frv_relocate_gprelu12
36
  PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
37
static bfd_reloc_status_type elf32_frv_relocate_gprello
38
  PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
39
static bfd_reloc_status_type elf32_frv_relocate_gprelhi
40
  PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *, bfd_byte *, bfd_vma));
41
static reloc_howto_type *frv_reloc_type_lookup
42
  PARAMS ((bfd *, bfd_reloc_code_real_type));
43
static void frv_info_to_howto_rela
44
  PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
45
static boolean elf32_frv_relocate_section
46
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
47
static boolean elf32_frv_add_symbol_hook
48
  PARAMS (( bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, const char **, flagword *, asection **, bfd_vma *));
49
static bfd_reloc_status_type frv_final_link_relocate
50
  PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma));
51
static boolean elf32_frv_gc_sweep_hook
52
  PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
53
static asection * elf32_frv_gc_mark_hook
54
  PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *));
55
static boolean elf32_frv_check_relocs
56
  PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
57
static int elf32_frv_machine PARAMS ((bfd *));
58
static boolean elf32_frv_object_p PARAMS ((bfd *));
59
static boolean frv_elf_set_private_flags PARAMS ((bfd *, flagword));
60
static boolean frv_elf_copy_private_bfd_data PARAMS ((bfd *, bfd *));
61
static boolean frv_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
62
static boolean frv_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
63
 
64
static reloc_howto_type elf32_frv_howto_table [] =
65
{
66
  /* This reloc does nothing.  */
67
  HOWTO (R_FRV_NONE,            /* type */
68
         0,                      /* rightshift */
69
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
70
         32,                    /* bitsize */
71
         false,                 /* pc_relative */
72
         0,                      /* bitpos */
73
         complain_overflow_bitfield, /* complain_on_overflow */
74
         bfd_elf_generic_reloc, /* special_function */
75
         "R_FRV_NONE",          /* name */
76
         false,                 /* partial_inplace */
77
         0,                      /* src_mask */
78
         0,                      /* dst_mask */
79
         false),                /* pcrel_offset */
80
 
81
  /* A 32 bit absolute relocation.  */
82
  HOWTO (R_FRV_32,              /* type */
83
         0,                      /* rightshift */
84
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
85
         32,                    /* bitsize */
86
         false,                 /* pc_relative */
87
         0,                      /* bitpos */
88
         complain_overflow_bitfield, /* complain_on_overflow */
89
         bfd_elf_generic_reloc, /* special_function */
90
         "R_FRV_32",            /* name */
91
         false,                 /* partial_inplace */
92
         0xffffffff,            /* src_mask */
93
         0xffffffff,            /* dst_mask */
94
         false),                /* pcrel_offset */
95
 
96
  /* A 16 bit pc-relative relocation.  */
97
  HOWTO (R_FRV_LABEL16,         /* type */
98
         0,                      /* rightshift */
99
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
100
         16,                    /* bitsize */
101
         true,                  /* pc_relative */
102
         0,                      /* bitpos */
103
         complain_overflow_bitfield, /* complain_on_overflow */
104
         bfd_elf_generic_reloc, /* special_function */
105
         "R_FRV_LABEL16",       /* name */
106
         false,                 /* partial_inplace */
107
         0xffff,                /* src_mask */
108
         0xffff,                /* dst_mask */
109
         true),                 /* pcrel_offset */
110
 
111
  /* A 24-bit pc-relative relocation.  */
112
  HOWTO (R_FRV_LABEL24, /* type */
113
         2,                     /* rightshift */
114
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
115
         26,                    /* bitsize */
116
         true,                  /* pc_relative */
117
         0,                      /* bitpos */
118
         complain_overflow_bitfield, /* complain_on_overflow */
119
         bfd_elf_generic_reloc, /* special_function */
120
         "R_FRV_LABEL24",       /* name */
121
         false,                 /* partial_inplace */
122
         0x7e03ffff,            /* src_mask */
123
         0x7e03ffff,            /* dst_mask */
124
         true),                 /* pcrel_offset */
125
 
126
  HOWTO (R_FRV_LO16,            /* type */
127
         0,                      /* rightshift */
128
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
129
         16,                    /* bitsize */
130
         false,                 /* pc_relative */
131
         0,                      /* bitpos */
132
         complain_overflow_dont, /* complain_on_overflow */
133
         bfd_elf_generic_reloc, /* special_function */
134
         "R_FRV_LO16",          /* name */
135
        false,                  /* partial_inplace */
136
         0xffff,                /* src_mask */
137
         0xffff,                /* dst_mask */
138
         false),                /* pcrel_offset */
139
 
140
  HOWTO (R_FRV_HI16,            /* type */
141
         0,                      /* rightshift */
142
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
143
         16,                    /* bitsize */
144
         false,                 /* pc_relative */
145
         0,                      /* bitpos */
146
         complain_overflow_dont, /* complain_on_overflow */
147
         bfd_elf_generic_reloc, /* special_function */
148
         "R_FRV_HI16",          /* name */
149
         false,                 /* partial_inplace */
150
         0xffff,                /* src_mask */
151
         0xffff,                /* dst_mask */
152
         false),                /* pcrel_offset */
153
 
154
  HOWTO (R_FRV_GPREL12,         /* type */
155
         0,                      /* rightshift */
156
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
157
         12,                    /* bitsize */
158
         false,                 /* pc_relative */
159
         0,                      /* bitpos */
160
         complain_overflow_dont, /* complain_on_overflow */
161
         bfd_elf_generic_reloc, /* special_function */
162
         "R_FRV_GPREL12",       /* name */
163
         false,                 /* partial_inplace */
164
         0xfff,                 /* src_mask */
165
         0xfff,                 /* dst_mask */
166
         false),                /* pcrel_offset */
167
 
168
  HOWTO (R_FRV_GPRELU12,        /* type */
169
         0,                      /* rightshift */
170
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
171
         12,                    /* bitsize */
172
         false,                 /* pc_relative */
173
         0,                      /* bitpos */
174
         complain_overflow_dont, /* complain_on_overflow */
175
         bfd_elf_generic_reloc, /* special_function */
176
         "R_FRV_GPRELU12",      /* name */
177
         false,                 /* partial_inplace */
178
         0xfff,                 /* src_mask */
179
         0x3f03f,               /* dst_mask */
180
         false),                /* pcrel_offset */
181
 
182
  HOWTO (R_FRV_GPREL32,         /* type */
183
         0,                      /* rightshift */
184
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
185
         32,                    /* bitsize */
186
         false,                 /* pc_relative */
187
         0,                      /* bitpos */
188
         complain_overflow_dont, /* complain_on_overflow */
189
         bfd_elf_generic_reloc, /* special_function */
190
         "R_FRV_GPREL32",       /* name */
191
         false,                 /* partial_inplace */
192
         0xffffffff,            /* src_mask */
193
         0xffffffff,            /* dst_mask */
194
         false),                /* pcrel_offset */
195
 
196
  HOWTO (R_FRV_GPRELHI,         /* type */
197
         0,                      /* rightshift */
198
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
199
         16,                    /* bitsize */
200
         false,                 /* pc_relative */
201
         0,                      /* bitpos */
202
         complain_overflow_dont, /* complain_on_overflow */
203
         bfd_elf_generic_reloc, /* special_function */
204
         "R_FRV_GPRELHI",       /* name */
205
         false,                 /* partial_inplace */
206
         0xffff,                        /* src_mask */
207
         0xffff,                /* dst_mask */
208
         false),                /* pcrel_offset */
209
 
210
  HOWTO (R_FRV_GPRELLO,         /* type */
211
         0,                      /* rightshift */
212
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
213
         16,                    /* bitsize */
214
         false,                 /* pc_relative */
215
         0,                      /* bitpos */
216
         complain_overflow_dont, /* complain_on_overflow */
217
         bfd_elf_generic_reloc, /* special_function */
218
         "R_FRV_GPRELLO",       /* name */
219
         false,                 /* partial_inplace */
220
         0xffff,                        /* src_mask */
221
         0xffff,                /* dst_mask */
222
         false),                /* pcrel_offset */
223
};
224
 
225
/* GNU extension to record C++ vtable hierarchy.  */
226
static reloc_howto_type elf32_frv_vtinherit_howto =
227
  HOWTO (R_FRV_GNU_VTINHERIT,   /* type */
228
         0,                     /* rightshift */
229
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
230
         0,                     /* bitsize */
231
         false,                 /* pc_relative */
232
         0,                     /* bitpos */
233
         complain_overflow_dont, /* complain_on_overflow */
234
         NULL,                  /* special_function */
235
         "R_FRV_GNU_VTINHERIT", /* name */
236
         false,                 /* partial_inplace */
237
         0,                     /* src_mask */
238
         0,                     /* dst_mask */
239
         false);                /* pcrel_offset */
240
 
241
  /* GNU extension to record C++ vtable member usage.  */
242
static reloc_howto_type elf32_frv_vtentry_howto =
243
  HOWTO (R_FRV_GNU_VTENTRY,     /* type */
244
         0,                     /* rightshift */
245
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
246
         0,                     /* bitsize */
247
         false,                 /* pc_relative */
248
         0,                     /* bitpos */
249
         complain_overflow_dont, /* complain_on_overflow */
250
         _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
251
         "R_FRV_GNU_VTENTRY",   /* name */
252
         false,                 /* partial_inplace */
253
         0,                     /* src_mask */
254
         0,                     /* dst_mask */
255
         false);                /* pcrel_offset */
256
 
257
/* Map BFD reloc types to FRV ELF reloc types.  */
258
#if 0
259
struct frv_reloc_map
260
{
261
  unsigned int bfd_reloc_val;
262
  unsigned int frv_reloc_val;
263
};
264
 
265
static const struct frv_reloc_map frv_reloc_map [] =
266
{
267
  { BFD_RELOC_NONE,           R_FRV_NONE },
268
  { BFD_RELOC_32,             R_FRV_32 },
269
  { BFD_RELOC_FRV_LABEL16,    R_FRV_LABEL16 },
270
  { BFD_RELOC_FRV_LABEL24,    R_FRV_LABEL24 },
271
  { BFD_RELOC_FRV_LO16,       R_FRV_LO16 },
272
  { BFD_RELOC_FRV_HI16,       R_FRV_HI16 },
273
  { BFD_RELOC_FRV_GPREL12,    R_FRV_GPREL12 },
274
  { BFD_RELOC_FRV_GPRELU12,   R_FRV_GPRELU12 },
275
  { BFD_RELOC_FRV_GPREL32,    R_FRV_GPREL32 },
276
  { BFD_RELOC_FRV_GPRELHI,    R_FRV_GPRELHI },
277
  { BFD_RELOC_FRV_GPRELLO,    R_FRV_GPRELLO },
278
  { BFD_RELOC_VTABLE_INHERIT, R_FRV_GNU_VTINHERIT },
279
  { BFD_RELOC_VTABLE_ENTRY,   R_FRV_GNU_VTENTRY },
280
};
281
#endif
282
 
283
/* Handle an FRV small data reloc.  */
284
 
285
static bfd_reloc_status_type
286
elf32_frv_relocate_gprel12 (info, input_bfd, input_section, relocation, contents, value)
287
     struct bfd_link_info *info;
288
     bfd *input_bfd;
289
     asection *input_section;
290
     Elf_Internal_Rela *relocation;
291
     bfd_byte *contents;
292
     bfd_vma value;
293
{
294
  bfd_vma insn;
295
  bfd_vma gp;
296
  struct bfd_link_hash_entry *h;
297
 
298
  h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
299
 
300
  gp = (h->u.def.value
301
        + h->u.def.section->output_section->vma
302
        + h->u.def.section->output_offset);
303
 
304
  value -= input_section->output_section->vma;
305
  value -= (gp - input_section->output_section->vma);
306
 
307
  insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
308
 
309
  value += relocation->r_addend;
310
 
311
  if ((long) value > 0x7ff || (long) value < -0x800)
312
    return bfd_reloc_overflow;
313
 
314
  bfd_put_32 (input_bfd,
315
              (insn & 0xfffff000) | (value & 0xfff),
316
              contents + relocation->r_offset);
317
 
318
  return bfd_reloc_ok;
319
}
320
 
321
/* Handle an FRV small data reloc. for the u12 field.  */
322
 
323
static bfd_reloc_status_type
324
elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, relocation, contents, value)
325
     struct bfd_link_info *info;
326
     bfd *input_bfd;
327
     asection *input_section;
328
     Elf_Internal_Rela *relocation;
329
     bfd_byte *contents;
330
     bfd_vma value;
331
{
332
  bfd_vma insn;
333
  bfd_vma gp;
334
  struct bfd_link_hash_entry *h;
335
  bfd_vma mask;
336
 
337
  h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
338
 
339
  gp = (h->u.def.value
340
        + h->u.def.section->output_section->vma
341
        + h->u.def.section->output_offset);
342
 
343
  value -= input_section->output_section->vma;
344
  value -= (gp - input_section->output_section->vma);
345
 
346
  insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
347
 
348
  value += relocation->r_addend;
349
 
350
  if ((long) value > 0x7ff || (long) value < -0x800)
351
    return bfd_reloc_overflow;
352
 
353
  /* The high 6 bits go into bits 17-12. The low 6 bits go into bits 5-0.  */
354
  mask = 0x3f03f;
355
  insn = (insn & ~mask) | ((value & 0xfc0) << 12) | (value & 0x3f);
356
 
357
  bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
358
 
359
  return bfd_reloc_ok;
360
}
361
 
362
/* Handle an FRV ELF HI16 reloc.  */
363
 
364
static bfd_reloc_status_type
365
elf32_frv_relocate_hi16 (input_bfd, relhi, contents, value)
366
     bfd *input_bfd;
367
     Elf_Internal_Rela *relhi;
368
     bfd_byte *contents;
369
     bfd_vma value;
370
{
371
  bfd_vma insn;
372
 
373
  insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
374
 
375
  value += relhi->r_addend;
376
  value = ((value >> 16) & 0xffff);
377
 
378
  insn = (insn & 0xffff0000) | value;
379
 
380
  if ((long) value > 0xffff || (long) value < -0x10000)
381
    return bfd_reloc_overflow;
382
 
383
  bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
384
  return bfd_reloc_ok;
385
 
386
}
387
static bfd_reloc_status_type
388
elf32_frv_relocate_lo16 (input_bfd, rello, contents, value)
389
     bfd *input_bfd;
390
     Elf_Internal_Rela *rello;
391
     bfd_byte *contents;
392
     bfd_vma value;
393
{
394
  bfd_vma insn;
395
 
396
  insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
397
 
398
  value += rello->r_addend;
399
  value = value & 0xffff;
400
 
401
  insn = (insn & 0xffff0000) | value;
402
 
403
  if ((long) value > 0xffff || (long) value < -0x10000)
404
    return bfd_reloc_overflow;
405
 
406
  bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
407
  return bfd_reloc_ok;
408
}
409
 
410
/* Perform the relocation for the CALL label24 instruction.  */
411
 
412
static bfd_reloc_status_type
413
elf32_frv_relocate_label24 (input_bfd, input_section, rello, contents, value)
414
     bfd *input_bfd;
415
     asection *input_section;
416
     Elf_Internal_Rela *rello;
417
     bfd_byte *contents;
418
     bfd_vma value;
419
{
420
  bfd_vma insn;
421
  bfd_vma label6;
422
  bfd_vma label18;
423
 
424
  /* The format for the call instruction is:
425
 
426
 
427
      label6 opcode  label18
428
 
429
    The branch calculation is: pc + (4*label24)
430
    where label24 is the concatenation of label6 and label18.  */
431
 
432
  /* Grab the instruction.  */
433
  insn = bfd_get_32 (input_bfd, contents + rello->r_offset);
434
 
435
  value -= input_section->output_section->vma + input_section->output_offset;
436
  value -= rello->r_offset;
437
  value += rello->r_addend;
438
 
439
  value = value >> 2;
440
 
441
  label6  = value & 0xfc0000;
442
  label6  = label6 << 7;
443
 
444
  label18 = value & 0x3ffff;
445
 
446
  insn = insn & 0x803c0000;
447
  insn = insn | label6;
448
  insn = insn | label18;
449
 
450
  bfd_put_32 (input_bfd, insn, contents + rello->r_offset);
451
 
452
  return bfd_reloc_ok;
453
}
454
 
455
static bfd_reloc_status_type
456
elf32_frv_relocate_gprelhi (info, input_bfd, input_section, relocation, contents, value)
457
     struct bfd_link_info *info;
458
     bfd *input_bfd;
459
     asection *input_section;
460
     Elf_Internal_Rela *relocation;
461
     bfd_byte *contents;
462
     bfd_vma value;
463
{
464
  bfd_vma insn;
465
  bfd_vma gp;
466
  struct bfd_link_hash_entry *h;
467
 
468
  h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
469
 
470
  gp = (h->u.def.value
471
        + h->u.def.section->output_section->vma
472
        + h->u.def.section->output_offset);
473
 
474
  value -= input_section->output_section->vma;
475
  value -= (gp - input_section->output_section->vma);
476
  value += relocation->r_addend;
477
  value = ((value >> 16) & 0xffff);
478
 
479
  if ((long) value > 0xffff || (long) value < -0x10000)
480
    return bfd_reloc_overflow;
481
 
482
  insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
483
  insn = (insn & 0xffff0000) | value;
484
 
485
  bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
486
  return bfd_reloc_ok;
487
}
488
 
489
static bfd_reloc_status_type
490
elf32_frv_relocate_gprello (info, input_bfd, input_section, relocation, contents, value)
491
     struct bfd_link_info *info;
492
     bfd *input_bfd;
493
     asection *input_section;
494
     Elf_Internal_Rela *relocation;
495
     bfd_byte *contents;
496
     bfd_vma value;
497
{
498
  bfd_vma insn;
499
  bfd_vma gp;
500
  struct bfd_link_hash_entry *h;
501
 
502
  h = bfd_link_hash_lookup (info->hash, "_gp", false, false, true);
503
 
504
  gp = (h->u.def.value
505
        + h->u.def.section->output_section->vma
506
        + h->u.def.section->output_offset);
507
 
508
  value -= input_section->output_section->vma;
509
  value -= (gp - input_section->output_section->vma);
510
  value += relocation->r_addend;
511
  value = value & 0xffff;
512
 
513
  if ((long) value > 0xffff || (long) value < -0x10000)
514
    return bfd_reloc_overflow;
515
 
516
  insn = bfd_get_32 (input_bfd, contents + relocation->r_offset);
517
  insn = (insn & 0xffff0000) | value;
518
 
519
  bfd_put_32 (input_bfd, insn, contents + relocation->r_offset);
520
 
521
 return bfd_reloc_ok;
522
}
523
 
524
static reloc_howto_type *
525
frv_reloc_type_lookup (abfd, code)
526
     bfd * abfd ATTRIBUTE_UNUSED;
527
     bfd_reloc_code_real_type code;
528
{
529
  switch (code)
530
    {
531
    default:
532
      break;
533
 
534
    case BFD_RELOC_NONE:
535
      return &elf32_frv_howto_table[ (int) R_FRV_NONE];
536
 
537
    case BFD_RELOC_32:
538
    case BFD_RELOC_CTOR:
539
      return &elf32_frv_howto_table[ (int) R_FRV_32];
540
 
541
    case BFD_RELOC_FRV_LABEL16:
542
      return &elf32_frv_howto_table[ (int) R_FRV_LABEL16];
543
 
544
    case BFD_RELOC_FRV_LABEL24:
545
      return &elf32_frv_howto_table[ (int) R_FRV_LABEL24];
546
 
547
    case BFD_RELOC_FRV_LO16:
548
      return &elf32_frv_howto_table[ (int) R_FRV_LO16];
549
 
550
    case BFD_RELOC_FRV_HI16:
551
      return &elf32_frv_howto_table[ (int) R_FRV_HI16];
552
 
553
    case BFD_RELOC_FRV_GPREL12:
554
      return &elf32_frv_howto_table[ (int) R_FRV_GPREL12];
555
 
556
    case BFD_RELOC_FRV_GPRELU12:
557
      return &elf32_frv_howto_table[ (int) R_FRV_GPRELU12];
558
 
559
    case BFD_RELOC_FRV_GPREL32:
560
      return &elf32_frv_howto_table[ (int) R_FRV_GPREL32];
561
 
562
    case BFD_RELOC_FRV_GPRELHI:
563
      return &elf32_frv_howto_table[ (int) R_FRV_GPRELHI];
564
 
565
    case BFD_RELOC_FRV_GPRELLO:
566
      return &elf32_frv_howto_table[ (int) R_FRV_GPRELLO];
567
 
568
    case BFD_RELOC_VTABLE_INHERIT:
569
      return &elf32_frv_vtinherit_howto;
570
 
571
    case BFD_RELOC_VTABLE_ENTRY:
572
      return &elf32_frv_vtentry_howto;
573
    }
574
 
575
  return NULL;
576
}
577
 
578
/* Set the howto pointer for an FRV ELF reloc.  */
579
 
580
static void
581
frv_info_to_howto_rela (abfd, cache_ptr, dst)
582
     bfd * abfd ATTRIBUTE_UNUSED;
583
     arelent * cache_ptr;
584
     Elf32_Internal_Rela * dst;
585
{
586
  unsigned int r_type;
587
 
588
  r_type = ELF32_R_TYPE (dst->r_info);
589
  switch (r_type)
590
    {
591
    case R_FRV_GNU_VTINHERIT:
592
      cache_ptr->howto = &elf32_frv_vtinherit_howto;
593
      break;
594
 
595
    case R_FRV_GNU_VTENTRY:
596
      cache_ptr->howto = &elf32_frv_vtentry_howto;
597
      break;
598
 
599
    default:
600
      cache_ptr->howto = & elf32_frv_howto_table [r_type];
601
      break;
602
    }
603
}
604
 
605
/* Perform a single relocation.  By default we use the standard BFD
606
   routines, but a few relocs, we have to do them ourselves.  */
607
 
608
static bfd_reloc_status_type
609
frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation)
610
     reloc_howto_type *  howto;
611
     bfd *               input_bfd;
612
     asection *          input_section;
613
     bfd_byte *          contents;
614
     Elf_Internal_Rela * rel;
615
     bfd_vma             relocation;
616
{
617
  return _bfd_final_link_relocate (howto, input_bfd, input_section,
618
                                   contents, rel->r_offset, relocation,
619
                                   rel->r_addend);
620
}
621
 
622
 
623
/* Relocate an FRV ELF section.
624
 
625
   The RELOCATE_SECTION function is called by the new ELF backend linker
626
   to handle the relocations for a section.
627
 
628
   The relocs are always passed as Rela structures; if the section
629
   actually uses Rel structures, the r_addend field will always be
630
   zero.
631
 
632
   This function is responsible for adjusting the section contents as
633
   necessary, and (if using Rela relocs and generating a relocateable
634
   output file) adjusting the reloc addend as necessary.
635
 
636
   This function does not have to worry about setting the reloc
637
   address or the reloc symbol index.
638
 
639
   LOCAL_SYMS is a pointer to the swapped in local symbols.
640
 
641
   LOCAL_SECTIONS is an array giving the section in the input file
642
   corresponding to the st_shndx field of each local symbol.
643
 
644
   The global hash table entry for the global symbols can be found
645
   via elf_sym_hashes (input_bfd).
646
 
647
   When generating relocateable output, this function must handle
648
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
649
   going to be the section symbol corresponding to the output
650
   section, which means that the addend must be adjusted
651
   accordingly.  */
652
 
653
static boolean
654
elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
655
                            contents, relocs, local_syms, local_sections)
656
     bfd *                   output_bfd ATTRIBUTE_UNUSED;
657
     struct bfd_link_info *  info;
658
     bfd *                   input_bfd;
659
     asection *              input_section;
660
     bfd_byte *              contents;
661
     Elf_Internal_Rela *     relocs;
662
     Elf_Internal_Sym *      local_syms;
663
     asection **             local_sections;
664
{
665
  Elf_Internal_Shdr *           symtab_hdr;
666
  struct elf_link_hash_entry ** sym_hashes;
667
  Elf_Internal_Rela *           rel;
668
  Elf_Internal_Rela *           relend;
669
 
670
  if (info->relocateable)
671
    return true;
672
 
673
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
674
  sym_hashes = elf_sym_hashes (input_bfd);
675
  relend     = relocs + input_section->reloc_count;
676
 
677
  for (rel = relocs; rel < relend; rel ++)
678
    {
679
      reloc_howto_type *           howto;
680
      unsigned long                r_symndx;
681
      Elf_Internal_Sym *           sym;
682
      asection *                   sec;
683
      struct elf_link_hash_entry * h;
684
      bfd_vma                      relocation;
685
      bfd_reloc_status_type        r;
686
      const char *                 name = NULL;
687
      int                          r_type;
688
 
689
      r_type = ELF32_R_TYPE (rel->r_info);
690
 
691
      if (   r_type == R_FRV_GNU_VTINHERIT
692
          || r_type == R_FRV_GNU_VTENTRY)
693
        continue;
694
 
695
      /* This is a final link.  */
696
      r_symndx = ELF32_R_SYM (rel->r_info);
697
      howto  = elf32_frv_howto_table + ELF32_R_TYPE (rel->r_info);
698
      h      = NULL;
699
      sym    = NULL;
700
      sec    = NULL;
701
 
702
      if (r_symndx < symtab_hdr->sh_info)
703
        {
704
          sym = local_syms + r_symndx;
705
          sec = local_sections [r_symndx];
706
          relocation = (sec->output_section->vma
707
                        + sec->output_offset
708
                        + sym->st_value);
709
 
710
          name = bfd_elf_string_from_elf_section
711
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
712
          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
713
        }
714
      else
715
        {
716
          h = sym_hashes [r_symndx - symtab_hdr->sh_info];
717
 
718
          while (h->root.type == bfd_link_hash_indirect
719
                 || h->root.type == bfd_link_hash_warning)
720
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
721
 
722
          name = h->root.root.string;
723
 
724
          if (h->root.type == bfd_link_hash_defined
725
              || h->root.type == bfd_link_hash_defweak)
726
            {
727
              sec = h->root.u.def.section;
728
              relocation = (h->root.u.def.value
729
                            + sec->output_section->vma
730
                            + sec->output_offset);
731
            }
732
          else if (h->root.type == bfd_link_hash_undefweak)
733
            {
734
              relocation = 0;
735
            }
736
          else
737
            {
738
              if (! ((*info->callbacks->undefined_symbol)
739
                     (info, h->root.root.string, input_bfd,
740
                      input_section, rel->r_offset, true)))
741
                return false;
742
              relocation = 0;
743
            }
744
        }
745
 
746
     if (r_type == R_FRV_HI16)
747
       r = elf32_frv_relocate_hi16 (input_bfd, rel, contents, relocation);
748
 
749
     else if (r_type == R_FRV_LO16)
750
       r = elf32_frv_relocate_lo16 (input_bfd, rel, contents, relocation);
751
 
752
     else if (r_type == R_FRV_LABEL24)
753
       r = elf32_frv_relocate_label24 (input_bfd, input_section, rel, contents, relocation);
754
 
755
     else if (r_type == R_FRV_GPREL12)
756
       r = elf32_frv_relocate_gprel12 (info, input_bfd, input_section, rel, contents, relocation);
757
 
758
     else if (r_type == R_FRV_GPRELU12)
759
       r = elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, rel, contents, relocation);
760
 
761
     else if (r_type == R_FRV_GPRELLO)
762
       r = elf32_frv_relocate_gprello (info, input_bfd, input_section, rel, contents, relocation);
763
 
764
     else if (r_type == R_FRV_GPRELHI)
765
       r = elf32_frv_relocate_gprelhi (info, input_bfd, input_section, rel, contents, relocation);
766
 
767
     else
768
       r = frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation);
769
 
770
      if (r != bfd_reloc_ok)
771
        {
772
          const char * msg = (const char *) NULL;
773
 
774
          switch (r)
775
            {
776
            case bfd_reloc_overflow:
777
              r = info->callbacks->reloc_overflow
778
                (info, name, howto->name, (bfd_vma) 0,
779
                 input_bfd, input_section, rel->r_offset);
780
              break;
781
 
782
            case bfd_reloc_undefined:
783
              r = info->callbacks->undefined_symbol
784
                (info, name, input_bfd, input_section, rel->r_offset, true);
785
              break;
786
 
787
            case bfd_reloc_outofrange:
788
              msg = _("internal error: out of range error");
789
              break;
790
 
791
            case bfd_reloc_notsupported:
792
              msg = _("internal error: unsupported relocation error");
793
              break;
794
 
795
            case bfd_reloc_dangerous:
796
              msg = _("internal error: dangerous relocation");
797
              break;
798
 
799
            default:
800
              msg = _("internal error: unknown error");
801
              break;
802
            }
803
 
804
          if (msg)
805
            r = info->callbacks->warning
806
              (info, msg, name, input_bfd, input_section, rel->r_offset);
807
 
808
          if (! r)
809
            return false;
810
        }
811
    }
812
 
813
  return true;
814
}
815
 
816
/* Return the section that should be marked against GC for a given
817
   relocation.  */
818
 
819
static asection *
820
elf32_frv_gc_mark_hook (sec, info, rel, h, sym)
821
     asection *                   sec;
822
     struct bfd_link_info *       info ATTRIBUTE_UNUSED;
823
     Elf_Internal_Rela *          rel;
824
     struct elf_link_hash_entry * h;
825
     Elf_Internal_Sym *           sym;
826
{
827
  if (h != NULL)
828
    {
829
      switch (ELF32_R_TYPE (rel->r_info))
830
        {
831
        case R_FRV_GNU_VTINHERIT:
832
        case R_FRV_GNU_VTENTRY:
833
          break;
834
 
835
        default:
836
          switch (h->root.type)
837
            {
838
            default:
839
              break;
840
 
841
            case bfd_link_hash_defined:
842
            case bfd_link_hash_defweak:
843
              return h->root.u.def.section;
844
 
845
            case bfd_link_hash_common:
846
              return h->root.u.c.p->section;
847
            }
848
        }
849
    }
850
  else
851
    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
852
 
853
  return NULL;
854
}
855
 
856
/* Update the got entry reference counts for the section being removed.  */
857
 
858
static boolean
859
elf32_frv_gc_sweep_hook (abfd, info, sec, relocs)
860
     bfd *                     abfd ATTRIBUTE_UNUSED;
861
     struct bfd_link_info *    info ATTRIBUTE_UNUSED;
862
     asection *                sec ATTRIBUTE_UNUSED;
863
     const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED;
864
{
865
  return true;
866
}
867
 
868
 
869
/* Hook called by the linker routine which adds symbols from an object
870
   file.  We use it to put .comm items in .scomm, and not .comm.  */
871
 
872
static boolean
873
elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
874
     bfd *abfd;
875
     struct bfd_link_info *info;
876
     const Elf_Internal_Sym *sym;
877
     const char **namep ATTRIBUTE_UNUSED;
878
     flagword *flagsp ATTRIBUTE_UNUSED;
879
     asection **secp;
880
     bfd_vma *valp;
881
{
882
  if (sym->st_shndx == SHN_COMMON
883
      && !info->relocateable
884
      && (int)sym->st_size <= (int)bfd_get_gp_size (abfd))
885
    {
886
      /* Common symbols less than or equal to -G nn bytes are
887
         automatically put into .sbss.  */
888
 
889
      asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
890
 
891
      if (scomm == NULL)
892
        {
893
          scomm = bfd_make_section (abfd, ".scommon");
894
          if (scomm == NULL
895
              || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
896
                                                       | SEC_IS_COMMON
897
                                                       | SEC_LINKER_CREATED)))
898
            return false;
899
        }
900
 
901
      *secp = scomm;
902
      *valp = sym->st_size;
903
    }
904
 
905
  return true;
906
}
907
/* Look through the relocs for a section during the first phase.
908
   Since we don't do .gots or .plts, we just need to consider the
909
   virtual table relocs for gc.  */
910
 
911
static boolean
912
elf32_frv_check_relocs (abfd, info, sec, relocs)
913
     bfd *abfd;
914
     struct bfd_link_info *info;
915
     asection *sec;
916
     const Elf_Internal_Rela *relocs;
917
{
918
  Elf_Internal_Shdr *symtab_hdr;
919
  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
920
  const Elf_Internal_Rela *rel;
921
  const Elf_Internal_Rela *rel_end;
922
 
923
  if (info->relocateable)
924
    return true;
925
 
926
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
927
  sym_hashes = elf_sym_hashes (abfd);
928
  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
929
  if (!elf_bad_symtab (abfd))
930
    sym_hashes_end -= symtab_hdr->sh_info;
931
 
932
  rel_end = relocs + sec->reloc_count;
933
  for (rel = relocs; rel < rel_end; rel++)
934
    {
935
      struct elf_link_hash_entry *h;
936
      unsigned long r_symndx;
937
 
938
      r_symndx = ELF32_R_SYM (rel->r_info);
939
      if (r_symndx < symtab_hdr->sh_info)
940
        h = NULL;
941
      else
942
        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
943
 
944
      switch (ELF32_R_TYPE (rel->r_info))
945
        {
946
        /* This relocation describes the C++ object vtable hierarchy.
947
           Reconstruct it for later use during GC.  */
948
        case R_FRV_GNU_VTINHERIT:
949
          if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
950
            return false;
951
          break;
952
 
953
        /* This relocation describes which C++ vtable entries are actually
954
           used.  Record for later use during GC.  */
955
        case R_FRV_GNU_VTENTRY:
956
          if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
957
            return false;
958
          break;
959
        }
960
    }
961
 
962
  return true;
963
}
964
 
965
 
966
/* Return the machine subcode from the ELF e_flags header.  */
967
 
968
static int
969
elf32_frv_machine (abfd)
970
     bfd *abfd;
971
{
972
  switch (elf_elfheader (abfd)->e_flags & EF_FRV_CPU_MASK)
973
    {
974
    default:                break;
975
    case EF_FRV_CPU_FR500:  return bfd_mach_fr500;
976
    case EF_FRV_CPU_FR400:  return bfd_mach_fr400;
977
    case EF_FRV_CPU_FR300:  return bfd_mach_fr300;
978
    case EF_FRV_CPU_SIMPLE: return bfd_mach_frvsimple;
979
    case EF_FRV_CPU_TOMCAT: return bfd_mach_frvtomcat;
980
    }
981
 
982
  return bfd_mach_frv;
983
}
984
 
985
/* Set the right machine number for a FRV ELF file.  */
986
 
987
static boolean
988
elf32_frv_object_p (abfd)
989
     bfd *abfd;
990
{
991
  bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd));
992
  return true;
993
}
994
 
995
/* Function to set the ELF flag bits.  */
996
 
997
static boolean
998
frv_elf_set_private_flags (abfd, flags)
999
     bfd *abfd;
1000
     flagword flags;
1001
{
1002
  elf_elfheader (abfd)->e_flags = flags;
1003
  elf_flags_init (abfd) = true;
1004
  return true;
1005
}
1006
 
1007
/* Copy backend specific data from one object module to another.  */
1008
 
1009
static boolean
1010
frv_elf_copy_private_bfd_data (ibfd, obfd)
1011
     bfd *ibfd;
1012
     bfd *obfd;
1013
{
1014
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1015
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1016
    return true;
1017
 
1018
  BFD_ASSERT (!elf_flags_init (obfd)
1019
              || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
1020
 
1021
  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
1022
  elf_flags_init (obfd) = true;
1023
  return true;
1024
}
1025
 
1026
/* Merge backend specific data from an object file to the output
1027
   object file when linking.  */
1028
 
1029
static boolean
1030
frv_elf_merge_private_bfd_data (ibfd, obfd)
1031
     bfd *ibfd;
1032
     bfd *obfd;
1033
{
1034
  flagword old_flags, old_partial;
1035
  flagword new_flags, new_partial;
1036
  boolean error = false;
1037
  char new_opt[80];
1038
  char old_opt[80];
1039
 
1040
  new_opt[0] = old_opt[0] = '\0';
1041
  new_flags = elf_elfheader (ibfd)->e_flags;
1042
  old_flags = elf_elfheader (obfd)->e_flags;
1043
 
1044
#ifdef DEBUG
1045
  (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
1046
                         old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
1047
                         bfd_get_filename (ibfd));
1048
#endif
1049
 
1050
  if (!elf_flags_init (obfd))                   /* First call, no flags set.  */
1051
    {
1052
      elf_flags_init (obfd) = true;
1053
      old_flags = new_flags;
1054
    }
1055
 
1056
  else if (new_flags == old_flags)              /* Compatible flags are ok.  */
1057
    ;
1058
 
1059
  else                                          /* Possibly incompatible flags.  */
1060
    {
1061
      /* Warn if different # of gprs are used.  Note, 0 means nothing is
1062
         said about the size of gprs.  */
1063
      new_partial = (new_flags & EF_FRV_GPR_MASK);
1064
      old_partial = (old_flags & EF_FRV_GPR_MASK);
1065
      if (new_partial == old_partial)
1066
        ;
1067
 
1068
      else if (new_partial == 0)
1069
        ;
1070
 
1071
      else if (old_partial == 0)
1072
        old_flags |= new_partial;
1073
 
1074
      else
1075
        {
1076
          switch (new_partial)
1077
            {
1078
            default:            strcat (new_opt, " -mgpr-??"); break;
1079
            case EF_FRV_GPR_32: strcat (new_opt, " -mgpr-32"); break;
1080
            case EF_FRV_GPR_64: strcat (new_opt, " -mgpr-64"); break;
1081
            }
1082
 
1083
          switch (old_partial)
1084
            {
1085
            default:            strcat (old_opt, " -mgpr-??"); break;
1086
            case EF_FRV_GPR_32: strcat (old_opt, " -mgpr-32"); break;
1087
            case EF_FRV_GPR_64: strcat (old_opt, " -mgpr-64"); break;
1088
            }
1089
        }
1090
 
1091
      /* Warn if different # of fprs are used.  Note, 0 means nothing is
1092
         said about the size of fprs.  */
1093
      new_partial = (new_flags & EF_FRV_FPR_MASK);
1094
      old_partial = (old_flags & EF_FRV_FPR_MASK);
1095
      if (new_partial == old_partial)
1096
        ;
1097
 
1098
      else if (new_partial == 0)
1099
        ;
1100
 
1101
      else if (old_partial == 0)
1102
        old_flags |= new_partial;
1103
 
1104
      else
1105
        {
1106
          switch (new_partial)
1107
            {
1108
            default:              strcat (new_opt, " -mfpr-?");      break;
1109
            case EF_FRV_FPR_32:   strcat (new_opt, " -mfpr-32");     break;
1110
            case EF_FRV_FPR_64:   strcat (new_opt, " -mfpr-64");     break;
1111
            case EF_FRV_FPR_NONE: strcat (new_opt, " -msoft-float"); break;
1112
            }
1113
 
1114
          switch (old_partial)
1115
            {
1116
            default:              strcat (old_opt, " -mfpr-?");      break;
1117
            case EF_FRV_FPR_32:   strcat (old_opt, " -mfpr-32");     break;
1118
            case EF_FRV_FPR_64:   strcat (old_opt, " -mfpr-64");     break;
1119
            case EF_FRV_FPR_NONE: strcat (old_opt, " -msoft-float"); break;
1120
            }
1121
        }
1122
 
1123
      /* Warn if different dword support was used.  Note, 0 means nothing is
1124
         said about the dword support.  */
1125
      new_partial = (new_flags & EF_FRV_DWORD_MASK);
1126
      old_partial = (old_flags & EF_FRV_DWORD_MASK);
1127
      if (new_partial == old_partial)
1128
        ;
1129
 
1130
      else if (new_partial == 0)
1131
        ;
1132
 
1133
      else if (old_partial == 0)
1134
        old_flags |= new_partial;
1135
 
1136
      else
1137
        {
1138
          switch (new_partial)
1139
            {
1140
            default:               strcat (new_opt, " -mdword-?");  break;
1141
            case EF_FRV_DWORD_YES: strcat (new_opt, " -mdword");    break;
1142
            case EF_FRV_DWORD_NO:  strcat (new_opt, " -mno-dword"); break;
1143
            }
1144
 
1145
          switch (old_partial)
1146
            {
1147
            default:               strcat (old_opt, " -mdword-?");  break;
1148
            case EF_FRV_DWORD_YES: strcat (old_opt, " -mdword");    break;
1149
            case EF_FRV_DWORD_NO:  strcat (old_opt, " -mno-dword"); break;
1150
            }
1151
        }
1152
 
1153
      /* Or in flags that accumulate (ie, if one module uses it, mark that the
1154
         feature is used.  */
1155
      old_flags |= new_flags & (EF_FRV_DOUBLE
1156
                                | EF_FRV_MEDIA
1157
                                | EF_FRV_MULADD
1158
                                | EF_FRV_NON_PIC_RELOCS);
1159
 
1160
      /* If any module was compiled without -G0, clear the G0 bit.  */
1161
      old_flags = ((old_flags & ~ EF_FRV_G0)
1162
                   | (old_flags & new_flags & EF_FRV_G0));
1163
 
1164
      /* If any module was compiled without -mnopack, clear the mnopack bit.  */
1165
      old_flags = ((old_flags & ~ EF_FRV_NOPACK)
1166
                   | (old_flags & new_flags & EF_FRV_NOPACK));
1167
 
1168
      /* We don't have to do anything if the pic flags are the same, or the new
1169
         module(s) were compiled with -mlibrary-pic.  */
1170
      new_partial = (new_flags & EF_FRV_PIC_FLAGS);
1171
      old_partial = (old_flags & EF_FRV_PIC_FLAGS);
1172
      if ((new_partial == old_partial) || ((new_partial & EF_FRV_LIBPIC) != 0))
1173
        ;
1174
 
1175
      /* If the old module(s) were compiled with -mlibrary-pic, copy in the pic
1176
         flags if any from the new module.  */
1177
      else if ((old_partial & EF_FRV_LIBPIC) != 0)
1178
        old_flags = (old_flags & ~ EF_FRV_PIC_FLAGS) | new_partial;
1179
 
1180
      /* If we have mixtures of -fpic and -fPIC, or in both bits.  */
1181
      else if (new_partial != 0 && old_partial != 0)
1182
        old_flags |= new_partial;
1183
 
1184
      /* One module was compiled for pic and the other was not, see if we have
1185
         had any relocations that are not pic-safe.  */
1186
      else
1187
        {
1188
          if ((old_flags & EF_FRV_NON_PIC_RELOCS) == 0)
1189
            old_flags |= new_partial;
1190
          else
1191
            {
1192
              old_flags &= ~ EF_FRV_PIC_FLAGS;
1193
#ifndef FRV_NO_PIC_ERROR
1194
              error = true;
1195
              (*_bfd_error_handler)
1196
                (_("%s: compiled with %s and linked with modules that use non-pic relocations"),
1197
                 bfd_get_filename (ibfd),
1198
                 (new_flags & EF_FRV_BIGPIC) ? "-fPIC" : "-fpic");
1199
#endif
1200
            }
1201
        }
1202
 
1203
      /* Warn if different cpu is used (allow a specific cpu to override
1204
         the generic cpu).  */
1205
      new_partial = (new_flags & EF_FRV_CPU_MASK);
1206
      old_partial = (old_flags & EF_FRV_CPU_MASK);
1207
      if (new_partial == old_partial)
1208
        ;
1209
 
1210
      else if (new_partial == EF_FRV_CPU_GENERIC)
1211
        ;
1212
 
1213
      else if (old_partial == EF_FRV_CPU_GENERIC)
1214
        old_flags = (old_flags & ~EF_FRV_CPU_MASK) | new_partial;
1215
 
1216
      else
1217
        {
1218
          switch (new_partial)
1219
            {
1220
            default:                 strcat (new_opt, " -mcpu=?");      break;
1221
            case EF_FRV_CPU_GENERIC: strcat (new_opt, " -mcpu=frv");    break;
1222
            case EF_FRV_CPU_SIMPLE:  strcat (new_opt, " -mcpu=simple"); break;
1223
            case EF_FRV_CPU_FR500:   strcat (new_opt, " -mcpu=fr500");  break;
1224
            case EF_FRV_CPU_FR400:   strcat (new_opt, " -mcpu=fr400");  break;
1225
            case EF_FRV_CPU_FR300:   strcat (new_opt, " -mcpu=fr300");  break;
1226
            case EF_FRV_CPU_TOMCAT:  strcat (new_opt, " -mcpu=tomcat"); break;
1227
            }
1228
 
1229
          switch (old_partial)
1230
            {
1231
            default:                 strcat (old_opt, " -mcpu=?");      break;
1232
            case EF_FRV_CPU_GENERIC: strcat (old_opt, " -mcpu=frv");    break;
1233
            case EF_FRV_CPU_SIMPLE:  strcat (old_opt, " -mcpu=simple"); break;
1234
            case EF_FRV_CPU_FR500:   strcat (old_opt, " -mcpu=fr500");  break;
1235
            case EF_FRV_CPU_FR400:   strcat (old_opt, " -mcpu=fr400");  break;
1236
            case EF_FRV_CPU_FR300:   strcat (old_opt, " -mcpu=fr300");  break;
1237
            case EF_FRV_CPU_TOMCAT:  strcat (old_opt, " -mcpu=tomcat"); break;
1238
            }
1239
        }
1240
 
1241
      /* Print out any mismatches from above.  */
1242
      if (new_opt[0])
1243
        {
1244
          error = true;
1245
          (*_bfd_error_handler)
1246
            (_("%s: compiled with %s and linked with modules compiled with %s"),
1247
             bfd_get_filename (ibfd), new_opt, old_opt);
1248
        }
1249
 
1250
      /* Warn about any other mismatches */
1251
      new_partial = (new_flags & ~ EF_FRV_ALL_FLAGS);
1252
      old_partial = (old_flags & ~ EF_FRV_ALL_FLAGS);
1253
      if (new_partial != old_partial)
1254
        {
1255
          old_flags |= new_partial;
1256
          error = true;
1257
          (*_bfd_error_handler)
1258
            (_("%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"),
1259
             bfd_get_filename (ibfd), (long)new_partial, (long)old_partial);
1260
        }
1261
    }
1262
 
1263
  /* If the cpu is -mcpu=simple, then set the -mnopack bit.  */
1264
  if ((old_flags & EF_FRV_CPU_MASK) == EF_FRV_CPU_SIMPLE)
1265
    old_flags |= EF_FRV_NOPACK;
1266
 
1267
  /* Update the old flags now with changes made above.  */
1268
  old_partial = elf_elfheader (obfd)->e_flags & EF_FRV_CPU_MASK;
1269
  elf_elfheader (obfd)->e_flags = old_flags;
1270
  if (old_partial != (old_flags & EF_FRV_CPU_MASK))
1271
    bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd));
1272
 
1273
  if (error)
1274
    bfd_set_error (bfd_error_bad_value);
1275
 
1276
  return !error;
1277
}
1278
 
1279
 
1280
boolean
1281
frv_elf_print_private_bfd_data (abfd, ptr)
1282
     bfd *abfd;
1283
     PTR ptr;
1284
{
1285
  FILE *file = (FILE *) ptr;
1286
  flagword flags;
1287
 
1288
  BFD_ASSERT (abfd != NULL && ptr != NULL);
1289
 
1290
  /* Print normal ELF private data.  */
1291
  _bfd_elf_print_private_bfd_data (abfd, ptr);
1292
 
1293
  flags = elf_elfheader (abfd)->e_flags;
1294
  fprintf (file, _("private flags = 0x%lx:"), (long)flags);
1295
 
1296
  switch (flags & EF_FRV_CPU_MASK)
1297
    {
1298
    default:                                                    break;
1299
    case EF_FRV_CPU_SIMPLE: fprintf (file, " -mcpu=simple");    break;
1300
    case EF_FRV_CPU_FR500:  fprintf (file, " -mcpu=fr500");     break;
1301
    case EF_FRV_CPU_FR400:  fprintf (file, " -mcpu=fr400");     break;
1302
    case EF_FRV_CPU_FR300:  fprintf (file, " -mcpu=fr300");     break;
1303
    case EF_FRV_CPU_TOMCAT: fprintf (file, " -mcpu=tomcat");    break;
1304
    }
1305
 
1306
  switch (flags & EF_FRV_GPR_MASK)
1307
    {
1308
    default:                                                    break;
1309
    case EF_FRV_GPR_32: fprintf (file, " -mgpr-32");            break;
1310
    case EF_FRV_GPR_64: fprintf (file, " -mgpr-64");            break;
1311
    }
1312
 
1313
  switch (flags & EF_FRV_FPR_MASK)
1314
    {
1315
    default:                                                    break;
1316
    case EF_FRV_FPR_32:   fprintf (file, " -mfpr-32");          break;
1317
    case EF_FRV_FPR_64:   fprintf (file, " -mfpr-64");          break;
1318
    case EF_FRV_FPR_NONE: fprintf (file, " -msoft-float");      break;
1319
    }
1320
 
1321
  switch (flags & EF_FRV_DWORD_MASK)
1322
    {
1323
    default:                                                    break;
1324
    case EF_FRV_DWORD_YES: fprintf (file, " -mdword");          break;
1325
    case EF_FRV_DWORD_NO:  fprintf (file, " -mno-dword");       break;
1326
    }
1327
 
1328
  if (flags & EF_FRV_DOUBLE)
1329
    fprintf (file, " -mdouble");
1330
 
1331
  if (flags & EF_FRV_MEDIA)
1332
    fprintf (file, " -mmedia");
1333
 
1334
  if (flags & EF_FRV_MULADD)
1335
    fprintf (file, " -mmuladd");
1336
 
1337
  if (flags & EF_FRV_PIC)
1338
    fprintf (file, " -fpic");
1339
 
1340
  if (flags & EF_FRV_BIGPIC)
1341
    fprintf (file, " -fPIC");
1342
 
1343
  if (flags & EF_FRV_NON_PIC_RELOCS)
1344
    fprintf (file, " non-pic relocations");
1345
 
1346
  if (flags & EF_FRV_G0)
1347
    fprintf (file, " -G0");
1348
 
1349
  fputc ('\n', file);
1350
  return true;
1351
}
1352
 
1353
 
1354
#define ELF_ARCH                bfd_arch_frv
1355
#define ELF_MACHINE_CODE        EM_CYGNUS_FRV
1356
#define ELF_MAXPAGESIZE         0x1000
1357
 
1358
#define TARGET_BIG_SYM          bfd_elf32_frv_vec
1359
#define TARGET_BIG_NAME         "elf32-frv"
1360
 
1361
#define elf_info_to_howto_rel                   NULL
1362
#define elf_info_to_howto                       frv_info_to_howto_rela
1363
#define elf_backend_relocate_section            elf32_frv_relocate_section
1364
#define elf_backend_gc_mark_hook                elf32_frv_gc_mark_hook
1365
#define elf_backend_gc_sweep_hook               elf32_frv_gc_sweep_hook
1366
#define elf_backend_check_relocs                elf32_frv_check_relocs
1367
#define elf_backend_object_p                    elf32_frv_object_p
1368
#define elf_backend_add_symbol_hook             elf32_frv_add_symbol_hook
1369
 
1370
#define elf_backend_can_gc_sections             1
1371
#define elf_backend_rela_normal                 1
1372
 
1373
#define bfd_elf32_bfd_reloc_type_lookup         frv_reloc_type_lookup
1374
#define bfd_elf32_bfd_set_private_flags         frv_elf_set_private_flags
1375
#define bfd_elf32_bfd_copy_private_bfd_data     frv_elf_copy_private_bfd_data
1376
#define bfd_elf32_bfd_merge_private_bfd_data    frv_elf_merge_private_bfd_data
1377
#define bfd_elf32_bfd_print_private_bfd_data    frv_elf_print_private_bfd_data
1378
 
1379
#include "elf32-target.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.