~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/bfd/elf32-iq2000.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* IQ2000-specific support for 32-bit ELF.
 
2
   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2012
 
3
   Free Software Foundation, Inc.
 
4
 
 
5
   This file is part of BFD, the Binary File Descriptor library.
 
6
 
 
7
   This program is free software; you can redistribute it and/or modify
 
8
   it under the terms of the GNU General Public License as published by
 
9
   the Free Software Foundation; either version 3 of the License, or
 
10
   (at your option) any later version.
 
11
 
 
12
   This program is distributed in the hope that it will be useful,
 
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
   GNU General Public License for more details.
 
16
 
 
17
   You should have received a copy of the GNU General Public License
 
18
   along with this program; if not, write to the Free Software
 
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
20
 
 
21
#include "sysdep.h"
 
22
#include "bfd.h"
 
23
#include "libbfd.h"
 
24
#include "elf-bfd.h"
 
25
#include "elf/iq2000.h"
 
26
 
 
27
/* Forward declarations.  */
 
28
 
 
29
static bfd_reloc_status_type iq2000_elf_howto_hi16_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 
30
 
 
31
 
 
32
static reloc_howto_type iq2000_elf_howto_table [] =
 
33
{
 
34
  /* This reloc does nothing.  */
 
35
 
 
36
  HOWTO (R_IQ2000_NONE,              /* type */
 
37
         0,                          /* rightshift */
 
38
         2,                          /* size (0 = byte, 1 = short, 2 = long) */
 
39
         32,                         /* bitsize */
 
40
         FALSE,                      /* pc_relative */
 
41
         0,                          /* bitpos */
 
42
         complain_overflow_bitfield, /* complain_on_overflow */
 
43
         bfd_elf_generic_reloc,      /* special_function */
 
44
         "R_IQ2000_NONE",            /* name */
 
45
         FALSE,                      /* partial_inplace */
 
46
         0,                          /* src_mask */
 
47
         0,                          /* dst_mask */
 
48
         FALSE),                     /* pcrel_offset */
 
49
 
 
50
  /* A 16 bit absolute relocation.  */
 
51
  HOWTO (R_IQ2000_16,                /* type */
 
52
         0,                          /* rightshift */
 
53
         1,                          /* size (0 = byte, 1 = short, 2 = long) */
 
54
         16,                         /* bitsize */
 
55
         FALSE,                      /* pc_relative */
 
56
         0,                          /* bitpos */
 
57
         complain_overflow_bitfield, /* complain_on_overflow */
 
58
         bfd_elf_generic_reloc,      /* special_function */
 
59
         "R_IQ2000_16",              /* name */
 
60
         FALSE,                      /* partial_inplace */
 
61
         0x0000,                     /* src_mask */
 
62
         0xffff,                     /* dst_mask */
 
63
         FALSE),                     /* pcrel_offset */
 
64
 
 
65
  /* A 32 bit absolute relocation.  */
 
66
  HOWTO (R_IQ2000_32,                /* type */
 
67
         0,                          /* rightshift */
 
68
         2,                          /* size (0 = byte, 1 = short, 2 = long) */
 
69
         31,                         /* bitsize */
 
70
         FALSE,                      /* pc_relative */
 
71
         0,                          /* bitpos */
 
72
         complain_overflow_bitfield, /* complain_on_overflow */
 
73
         bfd_elf_generic_reloc,      /* special_function */
 
74
         "R_IQ2000_32",              /* name */
 
75
         FALSE,                      /* partial_inplace */
 
76
         0x00000000,                 /* src_mask */
 
77
         0x7fffffff,                 /* dst_mask */
 
78
         FALSE),                     /* pcrel_offset */
 
79
 
 
80
  /* 26 bit branch address.  */
 
81
  HOWTO (R_IQ2000_26,           /* type */
 
82
         2,                     /* rightshift */
 
83
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
84
         26,                    /* bitsize */
 
85
         FALSE,                 /* pc_relative */
 
86
         0,                     /* bitpos */
 
87
         complain_overflow_dont, /* complain_on_overflow */
 
88
                                /* This needs complex overflow
 
89
                                   detection, because the upper four
 
90
                                   bits must match the PC.  */
 
91
         bfd_elf_generic_reloc, /* special_function */
 
92
         "R_IQ2000_26",         /* name */
 
93
         FALSE,                 /* partial_inplace */
 
94
         0x00000000,            /* src_mask */
 
95
         0x03ffffff,            /* dst_mask */
 
96
         FALSE),                /* pcrel_offset */
 
97
 
 
98
  /* 16 bit PC relative reference.  */
 
99
  HOWTO (R_IQ2000_PC16,         /* type */
 
100
         2,                     /* rightshift */
 
101
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
102
         16,                    /* bitsize */
 
103
         TRUE,                  /* pc_relative */
 
104
         0,                     /* bitpos */
 
105
         complain_overflow_signed, /* complain_on_overflow */
 
106
         bfd_elf_generic_reloc, /* special_function */
 
107
         "R_IQ2000_PC16",       /* name */
 
108
         FALSE,                 /* partial_inplace */
 
109
         0x0000,                /* src_mask */
 
110
         0xffff,                /* dst_mask */
 
111
         TRUE),                 /* pcrel_offset */
 
112
 
 
113
  /* high 16 bits of symbol value.  */
 
114
  HOWTO (R_IQ2000_HI16,         /* type */
 
115
         16,                    /* rightshift */
 
116
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
117
         15,                    /* bitsize */
 
118
         FALSE,                 /* pc_relative */
 
119
         0,                     /* bitpos */
 
120
         complain_overflow_dont, /* complain_on_overflow */
 
121
         iq2000_elf_howto_hi16_reloc,   /* special_function */
 
122
         "R_IQ2000_HI16",       /* name */
 
123
         FALSE,                 /* partial_inplace */
 
124
         0x0000,                /* src_mask */
 
125
         0x7fff,                /* dst_mask */
 
126
         FALSE),                /* pcrel_offset */
 
127
 
 
128
  /* Low 16 bits of symbol value.  */
 
129
  HOWTO (R_IQ2000_LO16,         /* type */
 
130
         0,                     /* rightshift */
 
131
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
132
         16,                    /* bitsize */
 
133
         FALSE,                 /* pc_relative */
 
134
         0,                     /* bitpos */
 
135
         complain_overflow_dont, /* complain_on_overflow */
 
136
         bfd_elf_generic_reloc, /* special_function */
 
137
         "R_IQ2000_LO16",       /* name */
 
138
         FALSE,                 /* partial_inplace */
 
139
         0x0000,                /* src_mask */
 
140
         0xffff,                /* dst_mask */
 
141
         FALSE),                /* pcrel_offset */
 
142
 
 
143
  /* 16-bit jump offset.  */
 
144
  HOWTO (R_IQ2000_OFFSET_16,    /* type */
 
145
         2,                     /* rightshift */
 
146
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
147
         16,                    /* bitsize */
 
148
         FALSE,                 /* pc_relative */
 
149
         0,                     /* bitpos */
 
150
         complain_overflow_dont, /* complain_on_overflow */
 
151
         bfd_elf_generic_reloc, /* special_function */
 
152
         "R_IQ2000_OFFSET_16",  /* name */
 
153
         FALSE,                 /* partial_inplace */
 
154
         0x0000,                /* src_mask */
 
155
         0xffff,                /* dst_mask */
 
156
         FALSE),                /* pcrel_offset */
 
157
 
 
158
  /* 21-bit jump offset.  */
 
159
  HOWTO (R_IQ2000_OFFSET_21,    /* type */
 
160
         2,                     /* rightshift */
 
161
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
162
         21,                    /* bitsize */
 
163
         FALSE,                 /* pc_relative */
 
164
         0,                     /* bitpos */
 
165
         complain_overflow_dont, /* complain_on_overflow */
 
166
         bfd_elf_generic_reloc, /* special_function */
 
167
         "R_IQ2000_OFFSET_21",  /* name */
 
168
         FALSE,                 /* partial_inplace */
 
169
         0x000000,              /* src_mask */
 
170
         0x1fffff,              /* dst_mask */
 
171
         FALSE),                /* pcrel_offset */
 
172
 
 
173
  /* unsigned high 16 bits of value.  */
 
174
  HOWTO (R_IQ2000_OFFSET_21,    /* type */
 
175
         16,                    /* rightshift */
 
176
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
177
         16,                    /* bitsize */
 
178
         FALSE,                 /* pc_relative */
 
179
         0,                     /* bitpos */
 
180
         complain_overflow_dont, /* complain_on_overflow */
 
181
         bfd_elf_generic_reloc, /* special_function */
 
182
         "R_IQ2000_UHI16",      /* name */
 
183
         FALSE,                 /* partial_inplace */
 
184
         0x0000,                /* src_mask */
 
185
         0x7fff,                /* dst_mask */
 
186
         FALSE),                /* pcrel_offset */
 
187
 
 
188
  /* A 32 bit absolute debug relocation.  */
 
189
  HOWTO (R_IQ2000_32_DEBUG,          /* type */
 
190
         0,                          /* rightshift */
 
191
         2,                          /* size (0 = byte, 1 = short, 2 = long) */
 
192
         32,                         /* bitsize */
 
193
         FALSE,                      /* pc_relative */
 
194
         0,                          /* bitpos */
 
195
         complain_overflow_bitfield, /* complain_on_overflow */
 
196
         bfd_elf_generic_reloc,      /* special_function */
 
197
         "R_IQ2000_32",              /* name */
 
198
         FALSE,                      /* partial_inplace */
 
199
         0x00000000,                 /* src_mask */
 
200
         0xffffffff,                 /* dst_mask */
 
201
         FALSE),                     /* pcrel_offset */
 
202
 
 
203
};
 
204
 
 
205
/* GNU extension to record C++ vtable hierarchy.  */
 
206
static reloc_howto_type iq2000_elf_vtinherit_howto =
 
207
  HOWTO (R_IQ2000_GNU_VTINHERIT,    /* type */
 
208
         0,                        /* rightshift */
 
209
         2,                        /* size (0 = byte, 1 = short, 2 = long) */
 
210
         0,                        /* bitsize */
 
211
         FALSE,                    /* pc_relative */
 
212
         0,                        /* bitpos */
 
213
         complain_overflow_dont,   /* complain_on_overflow */
 
214
         NULL,                     /* special_function */
 
215
         "R_IQ2000_GNU_VTINHERIT",  /* name */
 
216
         FALSE,                    /* partial_inplace */
 
217
         0,                        /* src_mask */
 
218
         0,                        /* dst_mask */
 
219
         FALSE);                   /* pcrel_offset */
 
220
 
 
221
/* GNU extension to record C++ vtable member usage.  */
 
222
static reloc_howto_type iq2000_elf_vtentry_howto =
 
223
  HOWTO (R_IQ2000_GNU_VTENTRY,     /* type */
 
224
         0,                        /* rightshift */
 
225
         2,                        /* size (0 = byte, 1 = short, 2 = long) */
 
226
         0,                        /* bitsize */
 
227
         FALSE,                    /* pc_relative */
 
228
         0,                        /* bitpos */
 
229
         complain_overflow_dont,   /* complain_on_overflow */
 
230
         NULL,                     /* special_function */
 
231
         "R_IQ2000_GNU_VTENTRY",    /* name */
 
232
         FALSE,                    /* partial_inplace */
 
233
         0,                        /* src_mask */
 
234
         0,                        /* dst_mask */
 
235
         FALSE);                   /* pcrel_offset */
 
236
 
 
237
 
 
238
static bfd_reloc_status_type
 
239
iq2000_elf_howto_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED,
 
240
                             arelent *reloc_entry,
 
241
                             asymbol *symbol,
 
242
                             void * data,
 
243
                             asection *input_section,
 
244
                             bfd *output_bfd,
 
245
                             char **error_message ATTRIBUTE_UNUSED)
 
246
{
 
247
  bfd_reloc_status_type ret;
 
248
  bfd_vma relocation;
 
249
 
 
250
  /* If we're relocating and this an external symbol,
 
251
     we don't want to change anything.  */
 
252
  if (output_bfd != (bfd *) NULL
 
253
      && (symbol->flags & BSF_SECTION_SYM) == 0
 
254
      && reloc_entry->addend == 0)
 
255
    {
 
256
      reloc_entry->address += input_section->output_offset;
 
257
      return bfd_reloc_ok;
 
258
    }
 
259
 
 
260
  if (bfd_is_com_section (symbol->section))
 
261
    relocation = 0;
 
262
  else
 
263
    relocation = symbol->value;
 
264
 
 
265
  relocation += symbol->section->output_section->vma;
 
266
  relocation += symbol->section->output_offset;
 
267
  relocation += reloc_entry->addend;
 
268
 
 
269
  /* If %lo will have sign-extension, compensate by add 0x10000 to hi portion.  */
 
270
  if (relocation & 0x8000)
 
271
    reloc_entry->addend += 0x10000;
 
272
 
 
273
  /* Now do the reloc in the usual way.  */
 
274
  ret = bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
 
275
                                input_section, output_bfd, error_message);
 
276
 
 
277
  /* Put it back the way it was.  */
 
278
  if (relocation & 0x8000)
 
279
    reloc_entry->addend -= 0x10000;
 
280
 
 
281
  return ret;
 
282
}
 
283
 
 
284
static bfd_reloc_status_type
 
285
iq2000_elf_relocate_hi16 (bfd *input_bfd,
 
286
                          Elf_Internal_Rela *relhi,
 
287
                          bfd_byte *contents,
 
288
                          bfd_vma value)
 
289
{
 
290
  bfd_vma insn;
 
291
 
 
292
  insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
 
293
 
 
294
  value += relhi->r_addend;
 
295
  value &= 0x7fffffff; /* Mask off top-bit which is Harvard mask bit.  */
 
296
 
 
297
  /* If top-bit of %lo value is on, this means that %lo will
 
298
     sign-propagate and so we compensate by adding 1 to %hi value.  */
 
299
  if (value & 0x8000)
 
300
    value += 0x10000;
 
301
 
 
302
  value >>= 16;
 
303
  insn = ((insn & ~0xFFFF) | value);
 
304
 
 
305
  bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
 
306
  return bfd_reloc_ok;
 
307
}
 
308
 
 
309
static bfd_reloc_status_type
 
310
iq2000_elf_relocate_offset16 (bfd *input_bfd,
 
311
                              Elf_Internal_Rela *rel,
 
312
                              bfd_byte *contents,
 
313
                              bfd_vma value,
 
314
                              bfd_vma location)
 
315
{
 
316
  bfd_vma insn;
 
317
  bfd_vma jtarget;
 
318
 
 
319
  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
 
320
 
 
321
  value += rel->r_addend;
 
322
 
 
323
  if (value & 3)
 
324
    return bfd_reloc_dangerous;
 
325
 
 
326
  jtarget = (value & 0x3fffc) | (location & 0xf0000000L);
 
327
 
 
328
  if (jtarget != value)
 
329
    return bfd_reloc_overflow;
 
330
 
 
331
  insn = (insn & ~0xFFFF) | ((value >> 2) & 0xFFFF);
 
332
 
 
333
  bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
 
334
  return bfd_reloc_ok;
 
335
}
 
336
 
 
337
/* Map BFD reloc types to IQ2000 ELF reloc types.  */
 
338
 
 
339
static reloc_howto_type *
 
340
iq2000_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
341
                          bfd_reloc_code_real_type code)
 
342
{
 
343
  /* Note that the iq2000_elf_howto_table is indxed by the R_
 
344
     constants.  Thus, the order that the howto records appear in the
 
345
     table *must* match the order of the relocation types defined in
 
346
     include/elf/iq2000.h.  */
 
347
 
 
348
  switch (code)
 
349
    {
 
350
    case BFD_RELOC_NONE:
 
351
      return &iq2000_elf_howto_table[ (int) R_IQ2000_NONE];
 
352
    case BFD_RELOC_16:
 
353
      return &iq2000_elf_howto_table[ (int) R_IQ2000_16];
 
354
    case BFD_RELOC_32:
 
355
      return &iq2000_elf_howto_table[ (int) R_IQ2000_32];
 
356
    case BFD_RELOC_MIPS_JMP:
 
357
      return &iq2000_elf_howto_table[ (int) R_IQ2000_26];
 
358
    case BFD_RELOC_IQ2000_OFFSET_16:
 
359
      return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_16];
 
360
    case BFD_RELOC_IQ2000_OFFSET_21:
 
361
      return &iq2000_elf_howto_table[ (int) R_IQ2000_OFFSET_21];
 
362
    case BFD_RELOC_16_PCREL_S2:
 
363
      return &iq2000_elf_howto_table[ (int) R_IQ2000_PC16];
 
364
    case BFD_RELOC_HI16:
 
365
      return &iq2000_elf_howto_table[ (int) R_IQ2000_HI16];
 
366
    case BFD_RELOC_IQ2000_UHI16:
 
367
      return &iq2000_elf_howto_table[ (int) R_IQ2000_UHI16];
 
368
    case BFD_RELOC_LO16:
 
369
      return &iq2000_elf_howto_table[ (int) R_IQ2000_LO16];
 
370
    case BFD_RELOC_VTABLE_INHERIT:
 
371
      return &iq2000_elf_vtinherit_howto;
 
372
    case BFD_RELOC_VTABLE_ENTRY:
 
373
      return &iq2000_elf_vtentry_howto;
 
374
    default:
 
375
      /* Pacify gcc -Wall.  */
 
376
      return NULL;
 
377
    }
 
378
  return NULL;
 
379
}
 
380
 
 
381
static reloc_howto_type *
 
382
iq2000_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
 
383
{
 
384
  unsigned int i;
 
385
 
 
386
  for (i = 0;
 
387
       i < (sizeof (iq2000_elf_howto_table)
 
388
            / sizeof (iq2000_elf_howto_table[0]));
 
389
       i++)
 
390
    if (iq2000_elf_howto_table[i].name != NULL
 
391
        && strcasecmp (iq2000_elf_howto_table[i].name, r_name) == 0)
 
392
      return &iq2000_elf_howto_table[i];
 
393
 
 
394
  if (strcasecmp (iq2000_elf_vtinherit_howto.name, r_name) == 0)
 
395
    return &iq2000_elf_vtinherit_howto;
 
396
  if (strcasecmp (iq2000_elf_vtentry_howto.name, r_name) == 0)
 
397
    return &iq2000_elf_vtentry_howto;
 
398
 
 
399
  return NULL;
 
400
}
 
401
 
 
402
/* Perform a single relocation.  By default we use the standard BFD
 
403
   routines.  */
 
404
 
 
405
static bfd_reloc_status_type
 
406
iq2000_final_link_relocate (reloc_howto_type *  howto,
 
407
                            bfd *               input_bfd,
 
408
                            asection *          input_section,
 
409
                            bfd_byte *          contents,
 
410
                            Elf_Internal_Rela * rel,
 
411
                            bfd_vma             relocation)
 
412
{
 
413
  return _bfd_final_link_relocate (howto, input_bfd, input_section,
 
414
                                   contents, rel->r_offset,
 
415
                                   relocation, rel->r_addend);
 
416
}
 
417
 
 
418
/* Set the howto pointer for a IQ2000 ELF reloc.  */
 
419
 
 
420
static void
 
421
iq2000_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
 
422
                           arelent * cache_ptr,
 
423
                           Elf_Internal_Rela * dst)
 
424
{
 
425
  unsigned int r_type;
 
426
 
 
427
  r_type = ELF32_R_TYPE (dst->r_info);
 
428
  switch (r_type)
 
429
    {
 
430
    case R_IQ2000_GNU_VTINHERIT:
 
431
      cache_ptr->howto = & iq2000_elf_vtinherit_howto;
 
432
      break;
 
433
 
 
434
    case R_IQ2000_GNU_VTENTRY:
 
435
      cache_ptr->howto = & iq2000_elf_vtentry_howto;
 
436
      break;
 
437
 
 
438
    default:
 
439
      cache_ptr->howto = & iq2000_elf_howto_table [r_type];
 
440
      break;
 
441
    }
 
442
}
 
443
 
 
444
/* Look through the relocs for a section during the first phase.
 
445
   Since we don't do .gots or .plts, we just need to consider the
 
446
   virtual table relocs for gc.  */
 
447
 
 
448
static bfd_boolean
 
449
iq2000_elf_check_relocs (bfd *abfd,
 
450
                         struct bfd_link_info *info,
 
451
                         asection *sec,
 
452
                         const Elf_Internal_Rela *relocs)
 
453
{
 
454
  Elf_Internal_Shdr *symtab_hdr;
 
455
  struct elf_link_hash_entry **sym_hashes;
 
456
  const Elf_Internal_Rela *rel;
 
457
  const Elf_Internal_Rela *rel_end;
 
458
  bfd_boolean changed = FALSE;
 
459
 
 
460
  if (info->relocatable)
 
461
    return TRUE;
 
462
 
 
463
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
 
464
  sym_hashes = elf_sym_hashes (abfd);
 
465
 
 
466
  rel_end = relocs + sec->reloc_count;
 
467
  for (rel = relocs; rel < rel_end; rel++)
 
468
    {
 
469
      struct elf_link_hash_entry *h;
 
470
      unsigned long r_symndx;
 
471
 
 
472
      r_symndx = ELF32_R_SYM (rel->r_info);
 
473
      if (r_symndx < symtab_hdr->sh_info)
 
474
        h = NULL;
 
475
      else
 
476
        {
 
477
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 
478
          while (h->root.type == bfd_link_hash_indirect
 
479
                 || h->root.type == bfd_link_hash_warning)
 
480
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
481
 
 
482
          /* PR15323, ref flags aren't set for references in the same
 
483
             object.  */
 
484
          h->root.non_ir_ref = 1;
 
485
        }
 
486
 
 
487
      switch (ELF32_R_TYPE (rel->r_info))
 
488
        {
 
489
          /* This relocation describes the C++ object vtable
 
490
             hierarchy.  Reconstruct it for later use during GC.  */
 
491
        case R_IQ2000_GNU_VTINHERIT:
 
492
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
 
493
            return FALSE;
 
494
          break;
 
495
 
 
496
          /* This relocation describes which C++ vtable entries
 
497
             are actually used.  Record for later use during GC.  */
 
498
        case R_IQ2000_GNU_VTENTRY:
 
499
          BFD_ASSERT (h != NULL);
 
500
          if (h != NULL
 
501
              && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 
502
            return FALSE;
 
503
          break;
 
504
 
 
505
        case R_IQ2000_32:
 
506
          /* For debug section, change to special harvard-aware relocations.  */
 
507
          if (CONST_STRNEQ (sec->name, ".debug")
 
508
              || CONST_STRNEQ (sec->name, ".stab")
 
509
              || CONST_STRNEQ (sec->name, ".eh_frame"))
 
510
            {
 
511
              ((Elf_Internal_Rela *) rel)->r_info
 
512
                = ELF32_R_INFO (ELF32_R_SYM (rel->r_info), R_IQ2000_32_DEBUG);
 
513
              changed = TRUE;
 
514
            }
 
515
          break;
 
516
        }
 
517
    }
 
518
 
 
519
  if (changed)
 
520
    /* Note that we've changed relocs, otherwise if !info->keep_memory
 
521
       we'll free the relocs and lose our changes.  */
 
522
    elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
 
523
 
 
524
  return TRUE;
 
525
}
 
526
 
 
527
 
 
528
/* Relocate a IQ2000 ELF section.
 
529
   There is some attempt to make this function usable for many architectures,
 
530
   both USE_REL and USE_RELA ['twould be nice if such a critter existed],
 
531
   if only to serve as a learning tool.
 
532
 
 
533
   The RELOCATE_SECTION function is called by the new ELF backend linker
 
534
   to handle the relocations for a section.
 
535
 
 
536
   The relocs are always passed as Rela structures; if the section
 
537
   actually uses Rel structures, the r_addend field will always be
 
538
   zero.
 
539
 
 
540
   This function is responsible for adjusting the section contents as
 
541
   necessary, and (if using Rela relocs and generating a relocatable
 
542
   output file) adjusting the reloc addend as necessary.
 
543
 
 
544
   This function does not have to worry about setting the reloc
 
545
   address or the reloc symbol index.
 
546
 
 
547
   LOCAL_SYMS is a pointer to the swapped in local symbols.
 
548
 
 
549
   LOCAL_SECTIONS is an array giving the section in the input file
 
550
   corresponding to the st_shndx field of each local symbol.
 
551
 
 
552
   The global hash table entry for the global symbols can be found
 
553
   via elf_sym_hashes (input_bfd).
 
554
 
 
555
   When generating relocatable output, this function must handle
 
556
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
 
557
   going to be the section symbol corresponding to the output
 
558
   section, which means that the addend must be adjusted
 
559
   accordingly.  */
 
560
 
 
561
static bfd_boolean
 
562
iq2000_elf_relocate_section (bfd *                   output_bfd ATTRIBUTE_UNUSED,
 
563
                             struct bfd_link_info *  info,
 
564
                             bfd *                   input_bfd,
 
565
                             asection *              input_section,
 
566
                             bfd_byte *              contents,
 
567
                             Elf_Internal_Rela *     relocs,
 
568
                             Elf_Internal_Sym *      local_syms,
 
569
                             asection **             local_sections)
 
570
{
 
571
  Elf_Internal_Shdr *           symtab_hdr;
 
572
  struct elf_link_hash_entry ** sym_hashes;
 
573
  Elf_Internal_Rela *           rel;
 
574
  Elf_Internal_Rela *           relend;
 
575
 
 
576
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
 
577
  sym_hashes = elf_sym_hashes (input_bfd);
 
578
  relend     = relocs + input_section->reloc_count;
 
579
 
 
580
  for (rel = relocs; rel < relend; rel ++)
 
581
    {
 
582
      reloc_howto_type *           howto;
 
583
      unsigned long                r_symndx;
 
584
      Elf_Internal_Sym *           sym;
 
585
      asection *                   sec;
 
586
      struct elf_link_hash_entry * h;
 
587
      bfd_vma                      relocation;
 
588
      bfd_reloc_status_type        r;
 
589
      const char *                 name = NULL;
 
590
      int                          r_type;
 
591
 
 
592
      r_type = ELF32_R_TYPE (rel->r_info);
 
593
 
 
594
      if (   r_type == R_IQ2000_GNU_VTINHERIT
 
595
          || r_type == R_IQ2000_GNU_VTENTRY)
 
596
        continue;
 
597
 
 
598
      r_symndx = ELF32_R_SYM (rel->r_info);
 
599
 
 
600
      howto  = iq2000_elf_howto_table + ELF32_R_TYPE (rel->r_info);
 
601
      h      = NULL;
 
602
      sym    = NULL;
 
603
      sec    = NULL;
 
604
 
 
605
      if (r_symndx < symtab_hdr->sh_info)
 
606
        {
 
607
          asection *osec;
 
608
 
 
609
          sym = local_syms + r_symndx;
 
610
          osec = sec = local_sections [r_symndx];
 
611
          if ((sec->flags & SEC_MERGE)
 
612
              && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
 
613
            /* This relocation is relative to a section symbol that is
 
614
               going to be merged.  Change it so that it is relative
 
615
               to the merged section symbol.  */
 
616
            rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym, &sec,
 
617
                                                    rel->r_addend);
 
618
 
 
619
          relocation = (sec->output_section->vma
 
620
                        + sec->output_offset
 
621
                        + sym->st_value);
 
622
 
 
623
          name = bfd_elf_string_from_elf_section
 
624
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
 
625
          name = (name == NULL) ? bfd_section_name (input_bfd, osec) : name;
 
626
        }
 
627
      else
 
628
        {
 
629
          bfd_boolean unresolved_reloc;
 
630
          bfd_boolean warned;
 
631
 
 
632
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
 
633
                                   r_symndx, symtab_hdr, sym_hashes,
 
634
                                   h, sec, relocation,
 
635
                                   unresolved_reloc, warned);
 
636
 
 
637
          name = h->root.root.string;
 
638
        }
 
639
 
 
640
      if (sec != NULL && discarded_section (sec))
 
641
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
 
642
                                         rel, 1, relend, howto, 0, contents);
 
643
 
 
644
      if (info->relocatable)
 
645
        continue;
 
646
 
 
647
      switch (r_type)
 
648
        {
 
649
        case R_IQ2000_HI16:
 
650
          r = iq2000_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
 
651
          break;
 
652
 
 
653
        case R_IQ2000_OFFSET_16:
 
654
          r = iq2000_elf_relocate_offset16 (input_bfd, rel, contents, relocation,
 
655
                                            input_section->output_section->vma
 
656
                                            + input_section->output_offset
 
657
                                            + rel->r_offset);
 
658
          break;
 
659
 
 
660
        case R_IQ2000_PC16:
 
661
          rel->r_addend -= 4;
 
662
          /* Fall through.  */
 
663
 
 
664
        default:
 
665
          r = iq2000_final_link_relocate (howto, input_bfd, input_section,
 
666
                                         contents, rel, relocation);
 
667
          break;
 
668
        }
 
669
 
 
670
      if (r != bfd_reloc_ok)
 
671
        {
 
672
          const char * msg = (const char *) NULL;
 
673
 
 
674
          switch (r)
 
675
            {
 
676
            case bfd_reloc_overflow:
 
677
              r = info->callbacks->reloc_overflow
 
678
                (info, (h ? &h->root : NULL), name, howto->name,
 
679
                 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
 
680
              break;
 
681
 
 
682
            case bfd_reloc_undefined:
 
683
              r = info->callbacks->undefined_symbol
 
684
                (info, name, input_bfd, input_section, rel->r_offset, TRUE);
 
685
              break;
 
686
 
 
687
            case bfd_reloc_outofrange:
 
688
              msg = _("internal error: out of range error");
 
689
              break;
 
690
 
 
691
            case bfd_reloc_notsupported:
 
692
              msg = _("internal error: unsupported relocation error");
 
693
              break;
 
694
 
 
695
            case bfd_reloc_dangerous:
 
696
              msg = _("internal error: dangerous relocation");
 
697
              break;
 
698
 
 
699
            default:
 
700
              msg = _("internal error: unknown error");
 
701
              break;
 
702
            }
 
703
 
 
704
          if (msg)
 
705
            r = info->callbacks->warning
 
706
              (info, msg, name, input_bfd, input_section, rel->r_offset);
 
707
 
 
708
          if (! r)
 
709
            return FALSE;
 
710
        }
 
711
    }
 
712
 
 
713
  return TRUE;
 
714
}
 
715
 
 
716
 
 
717
/* Return the section that should be marked against GC for a given
 
718
   relocation.  */
 
719
 
 
720
static asection *
 
721
iq2000_elf_gc_mark_hook (asection *sec,
 
722
                         struct bfd_link_info *info,
 
723
                         Elf_Internal_Rela *rel,
 
724
                         struct elf_link_hash_entry *h,
 
725
                         Elf_Internal_Sym *sym)
 
726
{
 
727
  if (h != NULL)
 
728
    switch (ELF32_R_TYPE (rel->r_info))
 
729
      {
 
730
      case R_IQ2000_GNU_VTINHERIT:
 
731
      case R_IQ2000_GNU_VTENTRY:
 
732
        return NULL;
 
733
      }
 
734
 
 
735
  return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 
736
}
 
737
 
 
738
 
 
739
/* Return the MACH for an e_flags value.  */
 
740
 
 
741
static int
 
742
elf32_iq2000_machine (bfd *abfd)
 
743
{
 
744
  switch (elf_elfheader (abfd)->e_flags & EF_IQ2000_CPU_MASK)
 
745
    {
 
746
    case EF_IQ2000_CPU_IQ10:
 
747
      return bfd_mach_iq10;
 
748
 
 
749
    case EF_IQ2000_CPU_IQ2000:
 
750
    default:
 
751
      return bfd_mach_iq2000;
 
752
    }
 
753
}
 
754
 
 
755
 
 
756
/* Function to set the ELF flag bits.  */
 
757
 
 
758
static bfd_boolean
 
759
iq2000_elf_set_private_flags (bfd *abfd, flagword flags)
 
760
{
 
761
  elf_elfheader (abfd)->e_flags = flags;
 
762
  elf_flags_init (abfd) = TRUE;
 
763
  return TRUE;
 
764
}
 
765
 
 
766
/* Copy backend specific data from one object module to another.  */
 
767
 
 
768
static bfd_boolean
 
769
iq2000_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 
770
{
 
771
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
 
772
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
 
773
    return TRUE;
 
774
 
 
775
  BFD_ASSERT (!elf_flags_init (obfd)
 
776
              || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
 
777
 
 
778
  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
 
779
  elf_flags_init (obfd) = TRUE;
 
780
 
 
781
  /* Copy object attributes.  */
 
782
  _bfd_elf_copy_obj_attributes (ibfd, obfd);
 
783
 
 
784
  return TRUE;
 
785
}
 
786
 
 
787
/* Merge backend specific data from an object
 
788
   file to the output object file when linking.  */
 
789
 
 
790
static bfd_boolean
 
791
iq2000_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 
792
{
 
793
  flagword old_flags, old_partial;
 
794
  flagword new_flags, new_partial;
 
795
  bfd_boolean error = FALSE;
 
796
  char new_opt[80];
 
797
  char old_opt[80];
 
798
 
 
799
  new_opt[0] = old_opt[0] = '\0';
 
800
  new_flags = elf_elfheader (ibfd)->e_flags;
 
801
  old_flags = elf_elfheader (obfd)->e_flags;
 
802
 
 
803
  if (!elf_flags_init (obfd))
 
804
    {
 
805
      /* First call, no flags set.  */
 
806
      elf_flags_init (obfd) = TRUE;
 
807
      elf_elfheader (obfd)->e_flags = new_flags;
 
808
    }
 
809
 
 
810
  else if (new_flags != old_flags)
 
811
    {
 
812
      /* Warn if different cpu is used, but allow a
 
813
         specific cpu to override the generic cpu.  */
 
814
      new_partial = (new_flags & EF_IQ2000_CPU_MASK);
 
815
      old_partial = (old_flags & EF_IQ2000_CPU_MASK);
 
816
 
 
817
      if (new_partial != old_partial)
 
818
        {
 
819
          switch (new_partial)
 
820
            {
 
821
            case EF_IQ2000_CPU_IQ10:
 
822
              strcat (new_opt, " -m10");
 
823
              break;
 
824
 
 
825
            default:
 
826
            case EF_IQ2000_CPU_IQ2000:
 
827
              strcat (new_opt, " -m2000");
 
828
              break;
 
829
            }
 
830
 
 
831
          switch (old_partial)
 
832
            {
 
833
            case EF_IQ2000_CPU_IQ10:
 
834
              strcat (old_opt, " -m10");
 
835
              break;
 
836
 
 
837
            default:
 
838
            case EF_IQ2000_CPU_IQ2000:
 
839
              strcat (old_opt, " -m2000");
 
840
              break;
 
841
            }
 
842
        }
 
843
 
 
844
      /* Print out any mismatches from above.  */
 
845
      if (new_opt[0])
 
846
        {
 
847
          error = TRUE;
 
848
          _bfd_error_handler
 
849
            (_("%s: compiled with %s and linked with modules compiled with %s"),
 
850
             bfd_get_filename (ibfd), new_opt, old_opt);
 
851
        }
 
852
 
 
853
      new_flags &= ~ EF_IQ2000_ALL_FLAGS;
 
854
      old_flags &= ~ EF_IQ2000_ALL_FLAGS;
 
855
 
 
856
      /* Warn about any other mismatches.  */
 
857
      if (new_flags != old_flags)
 
858
        {
 
859
          error = TRUE;
 
860
 
 
861
          _bfd_error_handler
 
862
            (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
 
863
             bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
 
864
        }
 
865
    }
 
866
 
 
867
  if (error)
 
868
    bfd_set_error (bfd_error_bad_value);
 
869
 
 
870
  return !error;
 
871
}
 
872
 
 
873
 
 
874
static bfd_boolean
 
875
iq2000_elf_print_private_bfd_data (bfd *abfd, void * ptr)
 
876
{
 
877
  FILE *file = (FILE *) ptr;
 
878
  flagword flags;
 
879
 
 
880
  BFD_ASSERT (abfd != NULL && ptr != NULL);
 
881
 
 
882
  /* Print normal ELF private data.  */
 
883
  _bfd_elf_print_private_bfd_data (abfd, ptr);
 
884
 
 
885
  flags = elf_elfheader (abfd)->e_flags;
 
886
  fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
 
887
 
 
888
  switch (flags & EF_IQ2000_CPU_MASK)
 
889
    {
 
890
    case EF_IQ2000_CPU_IQ10:
 
891
      fprintf (file, " -m10");
 
892
      break;
 
893
    case EF_IQ2000_CPU_IQ2000:
 
894
      fprintf (file, " -m2000");
 
895
      break;
 
896
    default:
 
897
      break;
 
898
    }
 
899
 
 
900
  fputc ('\n', file);
 
901
  return TRUE;
 
902
}
 
903
 
 
904
static
 
905
bfd_boolean
 
906
iq2000_elf_object_p (bfd *abfd)
 
907
{
 
908
  bfd_default_set_arch_mach (abfd, bfd_arch_iq2000,
 
909
                             elf32_iq2000_machine (abfd));
 
910
  return TRUE;
 
911
}
 
912
 
 
913
 
 
914
#define ELF_ARCH                bfd_arch_iq2000
 
915
#define ELF_MACHINE_CODE        EM_IQ2000
 
916
#define ELF_MAXPAGESIZE         0x1000
 
917
 
 
918
#define TARGET_BIG_SYM          bfd_elf32_iq2000_vec
 
919
#define TARGET_BIG_NAME         "elf32-iq2000"
 
920
 
 
921
#define elf_info_to_howto_rel                   NULL
 
922
#define elf_info_to_howto                       iq2000_info_to_howto_rela
 
923
#define elf_backend_relocate_section            iq2000_elf_relocate_section
 
924
#define elf_backend_gc_mark_hook                iq2000_elf_gc_mark_hook
 
925
#define elf_backend_check_relocs                iq2000_elf_check_relocs
 
926
#define elf_backend_object_p                    iq2000_elf_object_p
 
927
#define elf_backend_rela_normal                 1
 
928
 
 
929
#define elf_backend_can_gc_sections             1
 
930
 
 
931
#define bfd_elf32_bfd_reloc_type_lookup         iq2000_reloc_type_lookup
 
932
#define bfd_elf32_bfd_reloc_name_lookup iq2000_reloc_name_lookup
 
933
#define bfd_elf32_bfd_set_private_flags         iq2000_elf_set_private_flags
 
934
#define bfd_elf32_bfd_copy_private_bfd_data     iq2000_elf_copy_private_bfd_data
 
935
#define bfd_elf32_bfd_merge_private_bfd_data    iq2000_elf_merge_private_bfd_data
 
936
#define bfd_elf32_bfd_print_private_bfd_data    iq2000_elf_print_private_bfd_data
 
937
 
 
938
#include "elf32-target.h"