~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/bfd/elf32-frv.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 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
    0 000000 0001111 000000000000000000 
 
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
   There is some attempt to make this function usable for many architectures,
 
625
   both USE_REL and USE_RELA ['twould be nice if such a critter existed],
 
626
   if only to serve as a learning tool.
 
627
 
 
628
   The RELOCATE_SECTION function is called by the new ELF backend linker
 
629
   to handle the relocations for a section.
 
630
 
 
631
   The relocs are always passed as Rela structures; if the section
 
632
   actually uses Rel structures, the r_addend field will always be
 
633
   zero.
 
634
 
 
635
   This function is responsible for adjusting the section contents as
 
636
   necessary, and (if using Rela relocs and generating a relocateable
 
637
   output file) adjusting the reloc addend as necessary.
 
638
 
 
639
   This function does not have to worry about setting the reloc
 
640
   address or the reloc symbol index.
 
641
 
 
642
   LOCAL_SYMS is a pointer to the swapped in local symbols.
 
643
 
 
644
   LOCAL_SECTIONS is an array giving the section in the input file
 
645
   corresponding to the st_shndx field of each local symbol.
 
646
 
 
647
   The global hash table entry for the global symbols can be found
 
648
   via elf_sym_hashes (input_bfd).
 
649
 
 
650
   When generating relocateable output, this function must handle
 
651
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
 
652
   going to be the section symbol corresponding to the output
 
653
   section, which means that the addend must be adjusted
 
654
   accordingly.  */
 
655
 
 
656
static boolean
 
657
elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
 
658
                           contents, relocs, local_syms, local_sections)
 
659
     bfd *                   output_bfd ATTRIBUTE_UNUSED;
 
660
     struct bfd_link_info *  info;
 
661
     bfd *                   input_bfd;
 
662
     asection *              input_section;
 
663
     bfd_byte *              contents;
 
664
     Elf_Internal_Rela *     relocs;
 
665
     Elf_Internal_Sym *      local_syms;
 
666
     asection **             local_sections;
 
667
{
 
668
  Elf_Internal_Shdr *           symtab_hdr;
 
669
  struct elf_link_hash_entry ** sym_hashes;
 
670
  Elf_Internal_Rela *           rel;
 
671
  Elf_Internal_Rela *           relend;
 
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
      r_symndx = ELF32_R_SYM (rel->r_info);
 
696
 
 
697
      if (info->relocateable)
 
698
        {
 
699
          /* This is a relocateable link.  We don't have to change
 
700
             anything, unless the reloc is against a section symbol,
 
701
             in which case we have to adjust according to where the
 
702
             section symbol winds up in the output section.  */
 
703
          if (r_symndx < symtab_hdr->sh_info)
 
704
            {
 
705
              sym = local_syms + r_symndx;
 
706
              
 
707
              if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
 
708
                {
 
709
                  sec = local_sections [r_symndx];
 
710
                  rel->r_addend += sec->output_offset + sym->st_value;
 
711
                }
 
712
            }
 
713
 
 
714
          continue;
 
715
        }
 
716
 
 
717
      /* This is a final link.  */
 
718
      howto  = elf32_frv_howto_table + ELF32_R_TYPE (rel->r_info);
 
719
      h      = NULL;
 
720
      sym    = NULL;
 
721
      sec    = NULL;
 
722
      
 
723
      if (r_symndx < symtab_hdr->sh_info)
 
724
        {
 
725
          sym = local_syms + r_symndx;
 
726
          sec = local_sections [r_symndx];
 
727
          relocation = (sec->output_section->vma
 
728
                        + sec->output_offset
 
729
                        + sym->st_value);
 
730
          
 
731
          name = bfd_elf_string_from_elf_section
 
732
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
 
733
          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
 
734
        }
 
735
      else
 
736
        {
 
737
          h = sym_hashes [r_symndx - symtab_hdr->sh_info];
 
738
          
 
739
          while (h->root.type == bfd_link_hash_indirect
 
740
                 || h->root.type == bfd_link_hash_warning)
 
741
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
742
 
 
743
          name = h->root.root.string;
 
744
          
 
745
          if (h->root.type == bfd_link_hash_defined
 
746
              || h->root.type == bfd_link_hash_defweak)
 
747
            {
 
748
              sec = h->root.u.def.section;
 
749
              relocation = (h->root.u.def.value
 
750
                            + sec->output_section->vma
 
751
                            + sec->output_offset);
 
752
            }
 
753
          else if (h->root.type == bfd_link_hash_undefweak)
 
754
            {
 
755
              relocation = 0;
 
756
            }
 
757
          else
 
758
            {
 
759
              if (! ((*info->callbacks->undefined_symbol)
 
760
                     (info, h->root.root.string, input_bfd,
 
761
                      input_section, rel->r_offset, true)))
 
762
                return false;
 
763
              relocation = 0;
 
764
            }
 
765
        }
 
766
      
 
767
     if (r_type == R_FRV_HI16)
 
768
       r = elf32_frv_relocate_hi16 (input_bfd, rel, contents, relocation);
 
769
 
 
770
     else if (r_type == R_FRV_LO16)
 
771
       r = elf32_frv_relocate_lo16 (input_bfd, rel, contents, relocation);
 
772
 
 
773
     else if (r_type == R_FRV_LABEL24)
 
774
       r = elf32_frv_relocate_label24 (input_bfd, input_section, rel, contents, relocation);
 
775
 
 
776
     else if (r_type == R_FRV_GPREL12)
 
777
       r = elf32_frv_relocate_gprel12 (info, input_bfd, input_section, rel, contents, relocation);
 
778
 
 
779
     else if (r_type == R_FRV_GPRELU12)
 
780
       r = elf32_frv_relocate_gprelu12 (info, input_bfd, input_section, rel, contents, relocation);
 
781
 
 
782
     else if (r_type == R_FRV_GPRELLO)
 
783
       r = elf32_frv_relocate_gprello (info, input_bfd, input_section, rel, contents, relocation);
 
784
 
 
785
     else if (r_type == R_FRV_GPRELHI)
 
786
       r = elf32_frv_relocate_gprelhi (info, input_bfd, input_section, rel, contents, relocation);
 
787
 
 
788
     else
 
789
       r = frv_final_link_relocate (howto, input_bfd, input_section, contents, rel, relocation);
 
790
 
 
791
      if (r != bfd_reloc_ok)
 
792
        {
 
793
          const char * msg = (const char *) NULL;
 
794
 
 
795
          switch (r)
 
796
            {
 
797
            case bfd_reloc_overflow:
 
798
              r = info->callbacks->reloc_overflow
 
799
                (info, name, howto->name, (bfd_vma) 0,
 
800
                 input_bfd, input_section, rel->r_offset);
 
801
              break;
 
802
              
 
803
            case bfd_reloc_undefined:
 
804
              r = info->callbacks->undefined_symbol
 
805
                (info, name, input_bfd, input_section, rel->r_offset, true);
 
806
              break;
 
807
              
 
808
            case bfd_reloc_outofrange:
 
809
              msg = _("internal error: out of range error");
 
810
              break;
 
811
 
 
812
            case bfd_reloc_notsupported:
 
813
              msg = _("internal error: unsupported relocation error");
 
814
              break;
 
815
 
 
816
            case bfd_reloc_dangerous:
 
817
              msg = _("internal error: dangerous relocation");
 
818
              break;
 
819
 
 
820
            default:
 
821
              msg = _("internal error: unknown error");
 
822
              break;
 
823
            }
 
824
 
 
825
          if (msg)
 
826
            r = info->callbacks->warning
 
827
              (info, msg, name, input_bfd, input_section, rel->r_offset);
 
828
 
 
829
          if (! r)
 
830
            return false;
 
831
        }
 
832
    }
 
833
 
 
834
  return true;
 
835
}
 
836
 
 
837
/* Return the section that should be marked against GC for a given
 
838
   relocation.  */
 
839
 
 
840
static asection *
 
841
elf32_frv_gc_mark_hook (sec, info, rel, h, sym)
 
842
     asection *                   sec;
 
843
     struct bfd_link_info *       info ATTRIBUTE_UNUSED;
 
844
     Elf_Internal_Rela *          rel;
 
845
     struct elf_link_hash_entry * h;
 
846
     Elf_Internal_Sym *           sym;
 
847
{
 
848
  if (h != NULL)
 
849
    {
 
850
      switch (ELF32_R_TYPE (rel->r_info))
 
851
        {
 
852
        case R_FRV_GNU_VTINHERIT:
 
853
        case R_FRV_GNU_VTENTRY:
 
854
          break;
 
855
 
 
856
        default:
 
857
          switch (h->root.type)
 
858
            {
 
859
            default:
 
860
              break;
 
861
 
 
862
            case bfd_link_hash_defined:
 
863
            case bfd_link_hash_defweak:
 
864
              return h->root.u.def.section;
 
865
 
 
866
            case bfd_link_hash_common:
 
867
              return h->root.u.c.p->section;
 
868
            }
 
869
        }
 
870
    }
 
871
  else
 
872
    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
 
873
 
 
874
  return NULL;
 
875
}
 
876
 
 
877
/* Update the got entry reference counts for the section being removed.  */
 
878
 
 
879
static boolean
 
880
elf32_frv_gc_sweep_hook (abfd, info, sec, relocs)
 
881
     bfd *                     abfd ATTRIBUTE_UNUSED;
 
882
     struct bfd_link_info *    info ATTRIBUTE_UNUSED;
 
883
     asection *                sec ATTRIBUTE_UNUSED;
 
884
     const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED;
 
885
{
 
886
  return true;
 
887
}
 
888
 
 
889
 
 
890
/* Hook called by the linker routine which adds symbols from an object
 
891
   file.  We use it to put .comm items in .scomm, and not .comm.  */
 
892
 
 
893
static boolean
 
894
elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
 
895
     bfd *abfd;
 
896
     struct bfd_link_info *info;
 
897
     const Elf_Internal_Sym *sym;
 
898
     const char **namep ATTRIBUTE_UNUSED;
 
899
     flagword *flagsp ATTRIBUTE_UNUSED;
 
900
     asection **secp;
 
901
     bfd_vma *valp;
 
902
{
 
903
  if (sym->st_shndx == SHN_COMMON
 
904
      && !info->relocateable
 
905
      && (int)sym->st_size <= (int)bfd_get_gp_size (abfd))
 
906
    {
 
907
      /* Common symbols less than or equal to -G nn bytes are
 
908
         automatically put into .sbss.  */
 
909
 
 
910
      asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
 
911
 
 
912
      if (scomm == NULL)
 
913
        {
 
914
          scomm = bfd_make_section (abfd, ".scommon");
 
915
          if (scomm == NULL
 
916
              || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
 
917
                                                       | SEC_IS_COMMON
 
918
                                                       | SEC_LINKER_CREATED)))
 
919
            return false;
 
920
        }
 
921
 
 
922
      *secp = scomm;
 
923
      *valp = sym->st_size;
 
924
    }
 
925
 
 
926
  return true;
 
927
}
 
928
/* Look through the relocs for a section during the first phase.
 
929
   Since we don't do .gots or .plts, we just need to consider the
 
930
   virtual table relocs for gc.  */
 
931
 
 
932
static boolean
 
933
elf32_frv_check_relocs (abfd, info, sec, relocs)
 
934
     bfd *abfd;
 
935
     struct bfd_link_info *info;
 
936
     asection *sec;
 
937
     const Elf_Internal_Rela *relocs;
 
938
{
 
939
  Elf_Internal_Shdr *symtab_hdr;
 
940
  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
 
941
  const Elf_Internal_Rela *rel;
 
942
  const Elf_Internal_Rela *rel_end;
 
943
 
 
944
  if (info->relocateable)
 
945
    return true;
 
946
 
 
947
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
 
948
  sym_hashes = elf_sym_hashes (abfd);
 
949
  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof(Elf32_External_Sym);
 
950
  if (!elf_bad_symtab (abfd))
 
951
    sym_hashes_end -= symtab_hdr->sh_info;
 
952
 
 
953
  rel_end = relocs + sec->reloc_count;
 
954
  for (rel = relocs; rel < rel_end; rel++)
 
955
    {
 
956
      struct elf_link_hash_entry *h;
 
957
      unsigned long r_symndx;
 
958
 
 
959
      r_symndx = ELF32_R_SYM (rel->r_info);
 
960
      if (r_symndx < symtab_hdr->sh_info)
 
961
        h = NULL;
 
962
      else
 
963
        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 
964
 
 
965
      switch (ELF32_R_TYPE (rel->r_info))
 
966
        {
 
967
        /* This relocation describes the C++ object vtable hierarchy.
 
968
           Reconstruct it for later use during GC.  */
 
969
        case R_FRV_GNU_VTINHERIT:
 
970
          if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
 
971
            return false;
 
972
          break;
 
973
 
 
974
        /* This relocation describes which C++ vtable entries are actually
 
975
           used.  Record for later use during GC.  */
 
976
        case R_FRV_GNU_VTENTRY:
 
977
          if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 
978
            return false;
 
979
          break;
 
980
        }
 
981
    }
 
982
 
 
983
  return true;
 
984
}
 
985
 
 
986
 
 
987
/* Return the machine subcode from the ELF e_flags header.  */
 
988
 
 
989
static int
 
990
elf32_frv_machine (abfd)
 
991
     bfd *abfd;
 
992
{
 
993
  switch (elf_elfheader (abfd)->e_flags & EF_FRV_CPU_MASK)
 
994
    {
 
995
    default:                break;
 
996
    case EF_FRV_CPU_FR500:  return bfd_mach_fr500;
 
997
    case EF_FRV_CPU_FR400:  return bfd_mach_fr400;
 
998
    case EF_FRV_CPU_FR300:  return bfd_mach_fr300;
 
999
    case EF_FRV_CPU_SIMPLE: return bfd_mach_frvsimple;
 
1000
    case EF_FRV_CPU_TOMCAT: return bfd_mach_frvtomcat;
 
1001
    }
 
1002
 
 
1003
  return bfd_mach_frv;
 
1004
}
 
1005
 
 
1006
/* Set the right machine number for a FRV ELF file.  */
 
1007
 
 
1008
static boolean
 
1009
elf32_frv_object_p (abfd)
 
1010
     bfd *abfd;
 
1011
{
 
1012
  bfd_default_set_arch_mach (abfd, bfd_arch_frv, elf32_frv_machine (abfd));
 
1013
  return true;
 
1014
}
 
1015
 
 
1016
/* Function to set the ELF flag bits.  */
 
1017
 
 
1018
static boolean
 
1019
frv_elf_set_private_flags (abfd, flags)
 
1020
     bfd *abfd;
 
1021
     flagword flags;
 
1022
{
 
1023
  elf_elfheader (abfd)->e_flags = flags;
 
1024
  elf_flags_init (abfd) = true;
 
1025
  return true;
 
1026
}
 
1027
 
 
1028
/* Copy backend specific data from one object module to another.  */
 
1029
 
 
1030
static boolean
 
1031
frv_elf_copy_private_bfd_data (ibfd, obfd)
 
1032
     bfd *ibfd;
 
1033
     bfd *obfd;
 
1034
{
 
1035
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
 
1036
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
 
1037
    return true;
 
1038
 
 
1039
  BFD_ASSERT (!elf_flags_init (obfd)
 
1040
              || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
 
1041
 
 
1042
  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
 
1043
  elf_flags_init (obfd) = true;
 
1044
  return true;
 
1045
}
 
1046
 
 
1047
/* Merge backend specific data from an object file to the output
 
1048
   object file when linking.  */
 
1049
 
 
1050
static boolean
 
1051
frv_elf_merge_private_bfd_data (ibfd, obfd)
 
1052
     bfd *ibfd;
 
1053
     bfd *obfd;
 
1054
{
 
1055
  flagword old_flags, old_partial;
 
1056
  flagword new_flags, new_partial;
 
1057
  boolean error = false;
 
1058
  char new_opt[80];
 
1059
  char old_opt[80];
 
1060
 
 
1061
  new_opt[0] = old_opt[0] = '\0';
 
1062
  new_flags = elf_elfheader (ibfd)->e_flags;
 
1063
  old_flags = elf_elfheader (obfd)->e_flags;
 
1064
 
 
1065
#ifdef DEBUG
 
1066
  (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
 
1067
                         old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
 
1068
                         bfd_get_filename (ibfd));
 
1069
#endif
 
1070
 
 
1071
  if (!elf_flags_init (obfd))                   /* First call, no flags set.  */
 
1072
    {
 
1073
      elf_flags_init (obfd) = true;
 
1074
      old_flags = new_flags;
 
1075
    }
 
1076
 
 
1077
  else if (new_flags == old_flags)              /* Compatible flags are ok.  */
 
1078
    ;
 
1079
 
 
1080
  else                                          /* Possibly incompatible flags.  */
 
1081
    {
 
1082
      /* Warn if different # of gprs are used.  Note, 0 means nothing is
 
1083
         said about the size of gprs.  */
 
1084
      new_partial = (new_flags & EF_FRV_GPR_MASK);
 
1085
      old_partial = (old_flags & EF_FRV_GPR_MASK);
 
1086
      if (new_partial == old_partial)
 
1087
        ;
 
1088
 
 
1089
      else if (new_partial == 0)
 
1090
        ;
 
1091
 
 
1092
      else if (old_partial == 0)
 
1093
        old_flags |= new_partial;
 
1094
 
 
1095
      else
 
1096
        {
 
1097
          switch (new_partial)
 
1098
            {
 
1099
            default:            strcat (new_opt, " -mgpr-??"); break;
 
1100
            case EF_FRV_GPR_32: strcat (new_opt, " -mgpr-32"); break;
 
1101
            case EF_FRV_GPR_64: strcat (new_opt, " -mgpr-64"); break;
 
1102
            }
 
1103
 
 
1104
          switch (old_partial)
 
1105
            {
 
1106
            default:            strcat (old_opt, " -mgpr-??"); break;
 
1107
            case EF_FRV_GPR_32: strcat (old_opt, " -mgpr-32"); break;
 
1108
            case EF_FRV_GPR_64: strcat (old_opt, " -mgpr-64"); break;
 
1109
            }
 
1110
        }
 
1111
 
 
1112
      /* Warn if different # of fprs are used.  Note, 0 means nothing is
 
1113
         said about the size of fprs.  */
 
1114
      new_partial = (new_flags & EF_FRV_FPR_MASK);
 
1115
      old_partial = (old_flags & EF_FRV_FPR_MASK);
 
1116
      if (new_partial == old_partial)
 
1117
        ;
 
1118
 
 
1119
      else if (new_partial == 0)
 
1120
        ;
 
1121
 
 
1122
      else if (old_partial == 0)
 
1123
        old_flags |= new_partial;
 
1124
 
 
1125
      else
 
1126
        {
 
1127
          switch (new_partial)
 
1128
            {
 
1129
            default:              strcat (new_opt, " -mfpr-?");      break;
 
1130
            case EF_FRV_FPR_32:   strcat (new_opt, " -mfpr-32");     break;
 
1131
            case EF_FRV_FPR_64:   strcat (new_opt, " -mfpr-64");     break;
 
1132
            case EF_FRV_FPR_NONE: strcat (new_opt, " -msoft-float"); break;
 
1133
            }
 
1134
 
 
1135
          switch (old_partial)
 
1136
            {
 
1137
            default:              strcat (old_opt, " -mfpr-?");      break;
 
1138
            case EF_FRV_FPR_32:   strcat (old_opt, " -mfpr-32");     break;
 
1139
            case EF_FRV_FPR_64:   strcat (old_opt, " -mfpr-64");     break;
 
1140
            case EF_FRV_FPR_NONE: strcat (old_opt, " -msoft-float"); break;
 
1141
            }
 
1142
        }
 
1143
 
 
1144
      /* Warn if different dword support was used.  Note, 0 means nothing is
 
1145
         said about the dword support.  */
 
1146
      new_partial = (new_flags & EF_FRV_DWORD_MASK);
 
1147
      old_partial = (old_flags & EF_FRV_DWORD_MASK);
 
1148
      if (new_partial == old_partial)
 
1149
        ;
 
1150
 
 
1151
      else if (new_partial == 0)
 
1152
        ;
 
1153
 
 
1154
      else if (old_partial == 0)
 
1155
        old_flags |= new_partial;
 
1156
 
 
1157
      else
 
1158
        {
 
1159
          switch (new_partial)
 
1160
            {
 
1161
            default:               strcat (new_opt, " -mdword-?");  break;
 
1162
            case EF_FRV_DWORD_YES: strcat (new_opt, " -mdword");    break;
 
1163
            case EF_FRV_DWORD_NO:  strcat (new_opt, " -mno-dword"); break;
 
1164
            }
 
1165
 
 
1166
          switch (old_partial)
 
1167
            {
 
1168
            default:               strcat (old_opt, " -mdword-?");  break;
 
1169
            case EF_FRV_DWORD_YES: strcat (old_opt, " -mdword");    break;
 
1170
            case EF_FRV_DWORD_NO:  strcat (old_opt, " -mno-dword"); break;
 
1171
            }
 
1172
        }
 
1173
 
 
1174
      /* Or in flags that accumulate (ie, if one module uses it, mark that the
 
1175
         feature is used.  */
 
1176
      old_flags |= new_flags & (EF_FRV_DOUBLE
 
1177
                                | EF_FRV_MEDIA
 
1178
                                | EF_FRV_MULADD
 
1179
                                | EF_FRV_NON_PIC_RELOCS);
 
1180
 
 
1181
      /* If any module was compiled without -G0, clear the G0 bit.  */
 
1182
      old_flags = ((old_flags & ~ EF_FRV_G0)
 
1183
                   | (old_flags & new_flags & EF_FRV_G0));
 
1184
 
 
1185
      /* If any module was compiled without -mnopack, clear the mnopack bit.  */
 
1186
      old_flags = ((old_flags & ~ EF_FRV_NOPACK)
 
1187
                   | (old_flags & new_flags & EF_FRV_NOPACK));
 
1188
 
 
1189
      /* We don't have to do anything if the pic flags are the same, or the new
 
1190
         module(s) were compiled with -mlibrary-pic.  */
 
1191
      new_partial = (new_flags & EF_FRV_PIC_FLAGS);
 
1192
      old_partial = (old_flags & EF_FRV_PIC_FLAGS);
 
1193
      if ((new_partial == old_partial) || ((new_partial & EF_FRV_LIBPIC) != 0))
 
1194
        ;
 
1195
 
 
1196
      /* If the old module(s) were compiled with -mlibrary-pic, copy in the pic
 
1197
         flags if any from the new module.  */
 
1198
      else if ((old_partial & EF_FRV_LIBPIC) != 0)
 
1199
        old_flags = (old_flags & ~ EF_FRV_PIC_FLAGS) | new_partial;
 
1200
 
 
1201
      /* If we have mixtures of -fpic and -fPIC, or in both bits.  */
 
1202
      else if (new_partial != 0 && old_partial != 0)
 
1203
        old_flags |= new_partial;
 
1204
 
 
1205
      /* One module was compiled for pic and the other was not, see if we have
 
1206
         had any relocations that are not pic-safe.  */
 
1207
      else
 
1208
        {
 
1209
          if ((old_flags & EF_FRV_NON_PIC_RELOCS) == 0)
 
1210
            old_flags |= new_partial;
 
1211
          else
 
1212
            {
 
1213
              old_flags &= ~ EF_FRV_PIC_FLAGS;
 
1214
#ifndef FRV_NO_PIC_ERROR
 
1215
              error = true;
 
1216
              (*_bfd_error_handler)
 
1217
                (_("%s: compiled with %s and linked with modules that use non-pic relocations"),
 
1218
                 bfd_get_filename (ibfd),
 
1219
                 (new_flags & EF_FRV_BIGPIC) ? "-fPIC" : "-fpic");
 
1220
#endif
 
1221
            }
 
1222
        }
 
1223
 
 
1224
      /* Warn if different cpu is used (allow a specific cpu to override
 
1225
         the generic cpu).  */
 
1226
      new_partial = (new_flags & EF_FRV_CPU_MASK);
 
1227
      old_partial = (old_flags & EF_FRV_CPU_MASK);
 
1228
      if (new_partial == old_partial)
 
1229
        ;
 
1230
 
 
1231
      else if (new_partial == EF_FRV_CPU_GENERIC)
 
1232
        ;
 
1233
 
 
1234
      else if (old_partial == EF_FRV_CPU_GENERIC)
 
1235
        old_flags = (old_flags & ~EF_FRV_CPU_MASK) | new_partial;
 
1236
 
 
1237
      else
 
1238
        {
 
1239
          switch (new_partial)
 
1240
            {
 
1241
            default:                 strcat (new_opt, " -mcpu=?");      break;
 
1242
            case EF_FRV_CPU_GENERIC: strcat (new_opt, " -mcpu=frv");    break;
 
1243
            case EF_FRV_CPU_SIMPLE:  strcat (new_opt, " -mcpu=simple"); break;
 
1244
            case EF_FRV_CPU_FR500:   strcat (new_opt, " -mcpu=fr500");  break;
 
1245
            case EF_FRV_CPU_FR400:   strcat (new_opt, " -mcpu=fr400");  break;
 
1246
            case EF_FRV_CPU_FR300:   strcat (new_opt, " -mcpu=fr300");  break;
 
1247
            case EF_FRV_CPU_TOMCAT:  strcat (new_opt, " -mcpu=tomcat"); break;
 
1248
            }
 
1249
 
 
1250
          switch (old_partial)
 
1251
            {
 
1252
            default:                 strcat (old_opt, " -mcpu=?");      break;
 
1253
            case EF_FRV_CPU_GENERIC: strcat (old_opt, " -mcpu=frv");    break;
 
1254
            case EF_FRV_CPU_SIMPLE:  strcat (old_opt, " -mcpu=simple"); break;
 
1255
            case EF_FRV_CPU_FR500:   strcat (old_opt, " -mcpu=fr500");  break;
 
1256
            case EF_FRV_CPU_FR400:   strcat (old_opt, " -mcpu=fr400");  break;
 
1257
            case EF_FRV_CPU_FR300:   strcat (old_opt, " -mcpu=fr300");  break;
 
1258
            case EF_FRV_CPU_TOMCAT:  strcat (old_opt, " -mcpu=tomcat"); break;
 
1259
            }
 
1260
        }
 
1261
      
 
1262
      /* Print out any mismatches from above.  */
 
1263
      if (new_opt[0])
 
1264
        {
 
1265
          error = true;
 
1266
          (*_bfd_error_handler)
 
1267
            (_("%s: compiled with %s and linked with modules compiled with %s"),
 
1268
             bfd_get_filename (ibfd), new_opt, old_opt);
 
1269
        }
 
1270
 
 
1271
      /* Warn about any other mismatches */
 
1272
      new_partial = (new_flags & ~ EF_FRV_ALL_FLAGS);
 
1273
      old_partial = (old_flags & ~ EF_FRV_ALL_FLAGS);
 
1274
      if (new_partial != old_partial)
 
1275
        {
 
1276
          old_flags |= new_partial;
 
1277
          error = true;
 
1278
          (*_bfd_error_handler)
 
1279
            (_("%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%lx)"),
 
1280
             bfd_get_filename (ibfd), (long)new_partial, (long)old_partial);
 
1281
        }
 
1282
    }
 
1283
 
 
1284
  /* If the cpu is -mcpu=simple, then set the -mnopack bit.  */
 
1285
  if ((old_flags & EF_FRV_CPU_MASK) == EF_FRV_CPU_SIMPLE)
 
1286
    old_flags |= EF_FRV_NOPACK;
 
1287
 
 
1288
  /* Update the old flags now with changes made above.  */
 
1289
  old_partial = elf_elfheader (obfd)->e_flags & EF_FRV_CPU_MASK;
 
1290
  elf_elfheader (obfd)->e_flags = old_flags;
 
1291
  if (old_partial != (old_flags & EF_FRV_CPU_MASK))
 
1292
    bfd_default_set_arch_mach (obfd, bfd_arch_frv, elf32_frv_machine (obfd));
 
1293
 
 
1294
  if (error)
 
1295
    bfd_set_error (bfd_error_bad_value);
 
1296
 
 
1297
  return !error;
 
1298
}
 
1299
 
 
1300
 
 
1301
boolean
 
1302
frv_elf_print_private_bfd_data (abfd, ptr)
 
1303
     bfd *abfd;
 
1304
     PTR ptr;
 
1305
{
 
1306
  FILE *file = (FILE *) ptr;
 
1307
  flagword flags;
 
1308
 
 
1309
  BFD_ASSERT (abfd != NULL && ptr != NULL);
 
1310
 
 
1311
  /* Print normal ELF private data.  */
 
1312
  _bfd_elf_print_private_bfd_data (abfd, ptr);
 
1313
 
 
1314
  flags = elf_elfheader (abfd)->e_flags;
 
1315
  fprintf (file, _("private flags = 0x%lx:"), (long)flags);
 
1316
 
 
1317
  switch (flags & EF_FRV_CPU_MASK)
 
1318
    {
 
1319
    default:                                                    break;
 
1320
    case EF_FRV_CPU_SIMPLE: fprintf (file, " -mcpu=simple");    break;
 
1321
    case EF_FRV_CPU_FR500:  fprintf (file, " -mcpu=fr500");     break;
 
1322
    case EF_FRV_CPU_FR400:  fprintf (file, " -mcpu=fr400");     break;
 
1323
    case EF_FRV_CPU_FR300:  fprintf (file, " -mcpu=fr300");     break;
 
1324
    case EF_FRV_CPU_TOMCAT: fprintf (file, " -mcpu=tomcat");    break;
 
1325
    }
 
1326
 
 
1327
  switch (flags & EF_FRV_GPR_MASK)
 
1328
    {
 
1329
    default:                                                    break;
 
1330
    case EF_FRV_GPR_32: fprintf (file, " -mgpr-32");            break;
 
1331
    case EF_FRV_GPR_64: fprintf (file, " -mgpr-64");            break;
 
1332
    }
 
1333
 
 
1334
  switch (flags & EF_FRV_FPR_MASK)
 
1335
    {
 
1336
    default:                                                    break;
 
1337
    case EF_FRV_FPR_32:   fprintf (file, " -mfpr-32");          break;
 
1338
    case EF_FRV_FPR_64:   fprintf (file, " -mfpr-64");          break;
 
1339
    case EF_FRV_FPR_NONE: fprintf (file, " -msoft-float");      break;
 
1340
    }
 
1341
 
 
1342
  switch (flags & EF_FRV_DWORD_MASK)
 
1343
    {
 
1344
    default:                                                    break;
 
1345
    case EF_FRV_DWORD_YES: fprintf (file, " -mdword");          break;
 
1346
    case EF_FRV_DWORD_NO:  fprintf (file, " -mno-dword");       break;
 
1347
    }
 
1348
 
 
1349
  if (flags & EF_FRV_DOUBLE)
 
1350
    fprintf (file, " -mdouble");
 
1351
 
 
1352
  if (flags & EF_FRV_MEDIA)
 
1353
    fprintf (file, " -mmedia");
 
1354
 
 
1355
  if (flags & EF_FRV_MULADD)
 
1356
    fprintf (file, " -mmuladd");
 
1357
 
 
1358
  if (flags & EF_FRV_PIC)
 
1359
    fprintf (file, " -fpic");
 
1360
 
 
1361
  if (flags & EF_FRV_BIGPIC)
 
1362
    fprintf (file, " -fPIC");
 
1363
 
 
1364
  if (flags & EF_FRV_NON_PIC_RELOCS)
 
1365
    fprintf (file, " non-pic relocations");
 
1366
 
 
1367
  if (flags & EF_FRV_G0)
 
1368
    fprintf (file, " -G0");
 
1369
 
 
1370
  fputc ('\n', file);
 
1371
  return true;
 
1372
}
 
1373
 
 
1374
 
 
1375
#define ELF_ARCH                bfd_arch_frv
 
1376
#define ELF_MACHINE_CODE        EM_CYGNUS_FRV
 
1377
#define ELF_MAXPAGESIZE         0x1000
 
1378
 
 
1379
#define TARGET_BIG_SYM          bfd_elf32_frv_vec
 
1380
#define TARGET_BIG_NAME         "elf32-frv"
 
1381
 
 
1382
#define elf_info_to_howto_rel                   NULL
 
1383
#define elf_info_to_howto                       frv_info_to_howto_rela
 
1384
#define elf_backend_relocate_section            elf32_frv_relocate_section
 
1385
#define elf_backend_gc_mark_hook                elf32_frv_gc_mark_hook
 
1386
#define elf_backend_gc_sweep_hook               elf32_frv_gc_sweep_hook
 
1387
#define elf_backend_check_relocs                elf32_frv_check_relocs
 
1388
#define elf_backend_object_p                    elf32_frv_object_p
 
1389
#define elf_backend_add_symbol_hook             elf32_frv_add_symbol_hook
 
1390
 
 
1391
#define elf_backend_can_gc_sections             1
 
1392
 
 
1393
#define bfd_elf32_bfd_reloc_type_lookup         frv_reloc_type_lookup
 
1394
#define bfd_elf32_bfd_set_private_flags         frv_elf_set_private_flags
 
1395
#define bfd_elf32_bfd_copy_private_bfd_data     frv_elf_copy_private_bfd_data
 
1396
#define bfd_elf32_bfd_merge_private_bfd_data    frv_elf_merge_private_bfd_data
 
1397
#define bfd_elf32_bfd_print_private_bfd_data    frv_elf_print_private_bfd_data
 
1398
 
 
1399
#include "elf32-target.h"