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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [bfd/] [elf32-xc16x.c] - Blame information for rev 818

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* Infineon XC16X-specific support for 16-bit ELF.
2
   Copyright 2006, 2007, 2009  Free Software Foundation, Inc.
3
   Contributed by KPIT Cummins Infosystems
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, 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include "sysdep.h"
23
#include "bfd.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
#include "elf/xc16x.h"
27
#include "dwarf2.h"
28
#include "libiberty.h"
29
 
30
static reloc_howto_type xc16x_elf_howto_table [] =
31
{
32
  /* This reloc does nothing.  */
33
  HOWTO (R_XC16X_NONE,          /* type */
34
         0,                      /* rightshift */
35
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
36
         16,                    /* bitsize */
37
         FALSE,                 /* pc_relative */
38
         0,                      /* bitpos */
39
         complain_overflow_bitfield, /* complain_on_overflow */
40
         bfd_elf_generic_reloc, /* special_function */
41
         "R_XC16X_NONE",        /* name */
42
         FALSE,                 /* partial_inplace */
43
         0,                      /* src_mask */
44
         0,                      /* dst_mask */
45
         FALSE),                /* pcrel_offset */
46
 
47
  /* An 8 bit absolute relocation.  */
48
  HOWTO (R_XC16X_ABS_8,         /* type */
49
         0,                      /* rightshift */
50
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
51
         8,                     /* bitsize */
52
         FALSE,                 /* pc_relative */
53
         8,                     /* bitpos */
54
         complain_overflow_bitfield, /* complain_on_overflow */
55
         bfd_elf_generic_reloc, /* special_function */
56
         "R_XC16X_ABS_8",       /* name */
57
         TRUE,                  /* partial_inplace */
58
         0x0000,                /* src_mask */
59
         0x00ff,                /* dst_mask */
60
         FALSE),                /* pcrel_offset */
61
 
62
  /* A 16 bit absolute relocation.  */
63
  HOWTO (R_XC16X_ABS_16,        /* type */
64
         0,                      /* rightshift */
65
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
66
         16,                    /* bitsize */
67
         FALSE,                 /* pc_relative */
68
         0,                      /* bitpos */
69
         complain_overflow_dont, /* complain_on_overflow */
70
         bfd_elf_generic_reloc, /* special_function */
71
         "R_XC16X_ABS_16",      /* name */
72
         TRUE,                  /* partial_inplace */
73
         0x00000000,            /* src_mask */
74
         0x0000ffff,            /* dst_mask */
75
         FALSE),                /* pcrel_offset */
76
 
77
  HOWTO (R_XC16X_ABS_32,        /* type */
78
         0,                      /* rightshift */
79
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
80
         32,                    /* bitsize */
81
         FALSE,                 /* pc_relative */
82
         0,                      /* bitpos */
83
         complain_overflow_bitfield, /* complain_on_overflow */
84
         bfd_elf_generic_reloc, /* special_function */
85
         "R_XC16X_ABS_32",      /* name */
86
         TRUE,                  /* partial_inplace */
87
         0x00000000,            /* src_mask */
88
         0xffffffff,            /* dst_mask */
89
         FALSE),                /* pcrel_offset */
90
 
91
 
92
  /* A PC relative 8 bit relocation.  */
93
  HOWTO (R_XC16X_8_PCREL,       /* type */
94
         0,                      /* rightshift */
95
         0,                      /* size (0 = byte, 1 = short, 2 = long) */
96
         8,                     /* bitsize */
97
         TRUE,                  /* pc_relative */
98
         8,                     /* bitpos */
99
         complain_overflow_signed, /* complain_on_overflow */
100
         bfd_elf_generic_reloc, /* special_function */
101
         "R_XC16X_8_PCREL",     /* name */
102
         FALSE,                 /* partial_inplace */
103
         0x0000,                /* src_mask */
104
         0x00ff,                /* dst_mask */
105
         TRUE),         /* pcrel_offset */
106
 
107
  /* Relocation regarding page number.  */
108
    HOWTO (R_XC16X_PAG, /* type */
109
         0,                      /* rightshift */
110
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
111
         16,                    /* bitsize */
112
         FALSE,                 /* pc_relative */
113
         0,                      /* bitpos */
114
         complain_overflow_signed, /* complain_on_overflow */
115
         bfd_elf_generic_reloc, /* special_function */
116
         "R_XC16X_PAG", /* name */
117
         TRUE,                  /* partial_inplace */
118
         0x00000000,            /* src_mask */
119
         0x0000ffff,            /* dst_mask */
120
         FALSE),                /* pcrel_offset */
121
 
122
 
123
  /* Relocation regarding page number.  */
124
      HOWTO (R_XC16X_POF,       /* type */
125
         0,                      /* rightshift */
126
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
127
         16,                    /* bitsize */
128
         FALSE,                 /* pc_relative */
129
         0,                      /* bitpos  */
130
         complain_overflow_signed, /* complain_on_overflow  */
131
         bfd_elf_generic_reloc, /* special_function  */
132
         "R_XC16X_POF", /* name  */
133
         TRUE,                  /* partial_inplace  */
134
         0x00000000,            /* src_mask  */
135
         0x0000ffff,            /* dst_mask  */
136
         FALSE),                /* pcrel_offset  */
137
 
138
 
139
  /* Relocation regarding segment number.   */
140
      HOWTO (R_XC16X_SEG,       /* type  */
141
         0,                      /* rightshift  */
142
         1,                     /* size (0 = byte, 1 = short, 2 = long)  */
143
         16,                    /* bitsize  */
144
         FALSE,                 /* pc_relative  */
145
         0,                      /* bitpos  */
146
         complain_overflow_signed, /* complain_on_overflow  */
147
         bfd_elf_generic_reloc, /* special_function  */
148
         "R_XC16X_SEG", /* name  */
149
         TRUE,                  /* partial_inplace  */
150
         0x00000000,            /* src_mask  */
151
         0x0000ffff,            /* dst_mask  */
152
         FALSE),                /* pcrel_offset  */
153
 
154
  /* Relocation regarding segment offset.  */
155
      HOWTO (R_XC16X_SOF,       /* type  */
156
         0,                      /* rightshift  */
157
         1,                     /* size (0 = byte, 1 = short, 2 = long)  */
158
         16,                    /* bitsize  */
159
         FALSE,                 /* pc_relative  */
160
         0,                      /* bitpos  */
161
         complain_overflow_signed, /* complain_on_overflow  */
162
         bfd_elf_generic_reloc, /* special_function  */
163
         "R_XC16X_SOF", /* name */
164
         TRUE,                  /* partial_inplace  */
165
         0x00000000,            /* src_mask  */
166
         0x0000ffff,            /* dst_mask  */
167
         FALSE)                 /* pcrel_offset  */
168
};
169
 
170
 
171
/* Map BFD reloc types to XC16X ELF reloc types.  */
172
 
173
struct xc16x_reloc_map
174
{
175
  bfd_reloc_code_real_type bfd_reloc_val;
176
  unsigned int xc16x_reloc_val;
177
};
178
 
179
static const struct xc16x_reloc_map xc16x_reloc_map [] =
180
{
181
  { BFD_RELOC_NONE,           R_XC16X_NONE },
182
  { BFD_RELOC_8,              R_XC16X_ABS_8 },
183
  { BFD_RELOC_16,             R_XC16X_ABS_16 },
184
  { BFD_RELOC_32,             R_XC16X_ABS_32 },
185
  { BFD_RELOC_8_PCREL,        R_XC16X_8_PCREL },
186
  { BFD_RELOC_XC16X_PAG,      R_XC16X_PAG},
187
  { BFD_RELOC_XC16X_POF,      R_XC16X_POF},
188
  { BFD_RELOC_XC16X_SEG,      R_XC16X_SEG},
189
  { BFD_RELOC_XC16X_SOF,      R_XC16X_SOF},
190
};
191
 
192
 
193
/* This function is used to search for correct relocation type from
194
   howto structure.  */
195
 
196
static reloc_howto_type *
197
xc16x_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
198
                         bfd_reloc_code_real_type code)
199
{
200
  unsigned int i;
201
 
202
  for (i = ARRAY_SIZE (xc16x_reloc_map); --i;)
203
    if (xc16x_reloc_map [i].bfd_reloc_val == code)
204
      return & xc16x_elf_howto_table [xc16x_reloc_map[i].xc16x_reloc_val];
205
 
206
  return NULL;
207
}
208
 
209
static reloc_howto_type *
210
xc16x_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
211
                         const char *r_name)
212
{
213
  unsigned int i;
214
 
215
  for (i = 0;
216
       i < sizeof (xc16x_elf_howto_table) / sizeof (xc16x_elf_howto_table[0]);
217
       i++)
218
    if (xc16x_elf_howto_table[i].name != NULL
219
        && strcasecmp (xc16x_elf_howto_table[i].name, r_name) == 0)
220
      return &xc16x_elf_howto_table[i];
221
 
222
  return NULL;
223
}
224
 
225
/* For a particular operand this function is
226
   called to finalise the type of relocation.  */
227
 
228
static void
229
elf32_xc16x_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
230
                           Elf_Internal_Rela *elf_reloc)
231
{
232
  unsigned int r;
233
  unsigned int i;
234
 
235
  r = ELF32_R_TYPE (elf_reloc->r_info);
236
  for (i = 0; i < ARRAY_SIZE (xc16x_elf_howto_table); i++)
237
    if (xc16x_elf_howto_table[i].type == r)
238
      {
239
        bfd_reloc->howto = &xc16x_elf_howto_table[i];
240
        return;
241
      }
242
  abort ();
243
}
244
 
245
static bfd_reloc_status_type
246
elf32_xc16x_final_link_relocate (unsigned long r_type,
247
                                 bfd *input_bfd,
248
                                 bfd *output_bfd ATTRIBUTE_UNUSED,
249
                                 asection *input_section ATTRIBUTE_UNUSED,
250
                                 bfd_byte *contents,
251
                                 bfd_vma offset,
252
                                 bfd_vma value,
253
                                 bfd_vma addend,
254
                                 struct bfd_link_info *info ATTRIBUTE_UNUSED,
255
                                 asection *sym_sec ATTRIBUTE_UNUSED,
256
                                 int is_local ATTRIBUTE_UNUSED)
257
{
258
  bfd_byte *hit_data = contents + offset;
259
  bfd_vma val1;
260
 
261
  switch (r_type)
262
    {
263
    case R_XC16X_NONE:
264
      return bfd_reloc_ok;
265
 
266
    case R_XC16X_ABS_16:
267
      value += addend;
268
      bfd_put_16 (input_bfd, value, hit_data);
269
      return bfd_reloc_ok;
270
 
271
    case R_XC16X_8_PCREL:
272
      bfd_put_8 (input_bfd, value, hit_data);
273
      return bfd_reloc_ok;
274
 
275
      /* Following case is to find page number from actual
276
         address for this divide value by 16k i.e. page size.  */
277
 
278
    case R_XC16X_PAG:
279
      value += addend;
280
      value /= 0x4000;
281
      bfd_put_16 (input_bfd, value, hit_data);
282
      return bfd_reloc_ok;
283
 
284
      /* Following case is to find page offset from actual address
285
         for this take modulo of value by 16k i.e. page size.  */
286
 
287
    case R_XC16X_POF:
288
      value += addend;
289
      value %= 0x4000;
290
      bfd_put_16 (input_bfd, value, hit_data);
291
      return bfd_reloc_ok;
292
 
293
      /* Following case is to find segment number from actual
294
         address for this divide value by 64k i.e. segment size.  */
295
 
296
    case R_XC16X_SEG:
297
      value += addend;
298
      value /= 0x10000;
299
      bfd_put_16 (input_bfd, value, hit_data);
300
      return bfd_reloc_ok;
301
 
302
      /* Following case is to find segment offset from actual address
303
         for this take modulo of value by 64k i.e. segment size.  */
304
 
305
    case R_XC16X_SOF:
306
      value += addend;
307
      value %= 0x10000;
308
      bfd_put_16 (input_bfd, value, hit_data);
309
      return bfd_reloc_ok;
310
 
311
    case R_XC16X_ABS_32:
312
      if (!strstr (input_section->name,".debug"))
313
        {
314
          value += addend;
315
          val1 = value;
316
          value %= 0x4000;
317
          val1 /= 0x4000;
318
          val1 = val1 << 16;
319
          value += val1;
320
          bfd_put_32 (input_bfd, value, hit_data);
321
        }
322
      else
323
        {
324
          value += addend;
325
          bfd_put_32 (input_bfd, value, hit_data);
326
        }
327
      return bfd_reloc_ok;
328
 
329
    default:
330
      return bfd_reloc_notsupported;
331
    }
332
}
333
 
334
static bfd_boolean
335
elf32_xc16x_relocate_section (bfd *output_bfd,
336
                              struct bfd_link_info *info,
337
                              bfd *input_bfd,
338
                              asection *input_section,
339
                              bfd_byte *contents,
340
                              Elf_Internal_Rela *relocs,
341
                              Elf_Internal_Sym *local_syms,
342
                              asection **local_sections)
343
{
344
  Elf_Internal_Shdr *symtab_hdr;
345
  struct elf_link_hash_entry **sym_hashes;
346
  Elf_Internal_Rela *rel, *relend;
347
 
348
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
349
  sym_hashes = elf_sym_hashes (input_bfd);
350
 
351
  rel = relocs;
352
  relend = relocs + input_section->reloc_count;
353
  for (; rel < relend; rel++)
354
    {
355
      unsigned int r_type;
356
      unsigned long r_symndx;
357
      Elf_Internal_Sym *sym;
358
      asection *sec;
359
      struct elf_link_hash_entry *h;
360
      bfd_vma relocation;
361
      bfd_reloc_status_type r;
362
 
363
      /* This is a final link.  */
364
      r_symndx = ELF32_R_SYM (rel->r_info);
365
      r_type = ELF32_R_TYPE (rel->r_info);
366
      h = NULL;
367
      sym = NULL;
368
      sec = NULL;
369
      if (r_symndx < symtab_hdr->sh_info)
370
        {
371
          sym = local_syms + r_symndx;
372
          sec = local_sections[r_symndx];
373
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
374
        }
375
      else
376
        {
377
          bfd_boolean unresolved_reloc, warned;
378
 
379
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
380
                                   r_symndx, symtab_hdr, sym_hashes,
381
                                   h, sec, relocation,
382
                                   unresolved_reloc, warned);
383
        }
384
 
385
      if (sec != NULL && elf_discarded_section (sec))
386
        {
387
          /* For relocs against symbols from removed linkonce sections,
388
             or sections discarded by a linker script, we just want the
389
             section contents zeroed.  Avoid any special processing.  */
390
          reloc_howto_type *howto;
391
          howto = xc16x_reloc_type_lookup (input_bfd, r_type);
392
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
393
          rel->r_info = 0;
394
          rel->r_addend = 0;
395
          continue;
396
        }
397
 
398
      if (info->relocatable)
399
        continue;
400
 
401
      r = elf32_xc16x_final_link_relocate (r_type, input_bfd, output_bfd,
402
                                           input_section,
403
                                           contents, rel->r_offset,
404
                                           relocation, rel->r_addend,
405
                                           info, sec, h == NULL);
406
    }
407
 
408
  return TRUE;
409
}
410
 
411
 
412
static void
413
elf32_xc16x_final_write_processing (bfd *abfd,
414
                                    bfd_boolean linker ATTRIBUTE_UNUSED)
415
{
416
  unsigned long val;
417
 
418
  switch (bfd_get_mach (abfd))
419
    {
420
    default:
421
    case bfd_mach_xc16x:
422
      val = 0x1000;
423
      break;
424
 
425
    case bfd_mach_xc16xl:
426
      val = 0x1001;
427
      break;
428
 
429
    case bfd_mach_xc16xs:
430
      val = 0x1002;
431
      break;
432
    }
433
 
434
  elf_elfheader (abfd)->e_flags |= val;
435
}
436
 
437
static unsigned long
438
elf32_xc16x_mach (flagword flags)
439
{
440
  switch (flags)
441
    {
442
    case 0x1000:
443
    default:
444
      return bfd_mach_xc16x;
445
 
446
    case 0x1001:
447
      return bfd_mach_xc16xl;
448
 
449
    case 0x1002:
450
      return bfd_mach_xc16xs;
451
    }
452
}
453
 
454
 
455
static bfd_boolean
456
elf32_xc16x_object_p (bfd *abfd)
457
{
458
  bfd_default_set_arch_mach (abfd, bfd_arch_xc16x,
459
                             elf32_xc16x_mach (elf_elfheader (abfd)->e_flags));
460
  return TRUE;
461
}
462
 
463
 
464
#define ELF_ARCH                bfd_arch_xc16x
465
#define ELF_MACHINE_CODE        EM_XC16X
466
#define ELF_MAXPAGESIZE         0x100
467
 
468
#define TARGET_LITTLE_SYM       bfd_elf32_xc16x_vec
469
#define TARGET_LITTLE_NAME      "elf32-xc16x"
470
#define elf_backend_final_write_processing      elf32_xc16x_final_write_processing
471
#define elf_backend_object_p            elf32_xc16x_object_p
472
#define elf_backend_can_gc_sections     1
473
#define bfd_elf32_bfd_reloc_type_lookup xc16x_reloc_type_lookup
474
#define bfd_elf32_bfd_reloc_name_lookup xc16x_reloc_name_lookup
475
#define elf_info_to_howto               elf32_xc16x_info_to_howto
476
#define elf_info_to_howto_rel           elf32_xc16x_info_to_howto
477
#define elf_backend_relocate_section    elf32_xc16x_relocate_section
478
#define elf_backend_rela_normal         1
479
 
480
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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