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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf32-xc16x.c] - Blame information for rev 146

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 khays
/* Infineon XC16X-specific support for 16-bit ELF.
2
   Copyright 2006, 2007, 2009, 2010  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
 
362
      /* This is a final link.  */
363
      r_symndx = ELF32_R_SYM (rel->r_info);
364
      r_type = ELF32_R_TYPE (rel->r_info);
365
      h = NULL;
366
      sym = NULL;
367
      sec = NULL;
368
      if (r_symndx < symtab_hdr->sh_info)
369
        {
370
          sym = local_syms + r_symndx;
371
          sec = local_sections[r_symndx];
372
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
373
        }
374
      else
375
        {
376
          bfd_boolean unresolved_reloc, warned;
377
 
378
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
379
                                   r_symndx, symtab_hdr, sym_hashes,
380
                                   h, sec, relocation,
381
                                   unresolved_reloc, warned);
382
        }
383
 
384
      if (sec != NULL && elf_discarded_section (sec))
385
        {
386
          /* For relocs against symbols from removed linkonce sections,
387
             or sections discarded by a linker script, we just want the
388
             section contents cleared.  Avoid any special processing.  */
389
          reloc_howto_type *howto;
390
          howto = xc16x_reloc_type_lookup (input_bfd, r_type);
391
          RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
392
                                           rel, relend, howto, contents);
393
        }
394
 
395
      if (info->relocatable)
396
        continue;
397
 
398
      elf32_xc16x_final_link_relocate (r_type, input_bfd, output_bfd,
399
                                       input_section,
400
                                       contents, rel->r_offset,
401
                                       relocation, rel->r_addend,
402
                                       info, sec, h == NULL);
403
    }
404
 
405
  return TRUE;
406
}
407
 
408
 
409
static void
410
elf32_xc16x_final_write_processing (bfd *abfd,
411
                                    bfd_boolean linker ATTRIBUTE_UNUSED)
412
{
413
  unsigned long val;
414
 
415
  switch (bfd_get_mach (abfd))
416
    {
417
    default:
418
    case bfd_mach_xc16x:
419
      val = 0x1000;
420
      break;
421
 
422
    case bfd_mach_xc16xl:
423
      val = 0x1001;
424
      break;
425
 
426
    case bfd_mach_xc16xs:
427
      val = 0x1002;
428
      break;
429
    }
430
 
431
  elf_elfheader (abfd)->e_flags |= val;
432
}
433
 
434
static unsigned long
435
elf32_xc16x_mach (flagword flags)
436
{
437
  switch (flags)
438
    {
439
    case 0x1000:
440
    default:
441
      return bfd_mach_xc16x;
442
 
443
    case 0x1001:
444
      return bfd_mach_xc16xl;
445
 
446
    case 0x1002:
447
      return bfd_mach_xc16xs;
448
    }
449
}
450
 
451
 
452
static bfd_boolean
453
elf32_xc16x_object_p (bfd *abfd)
454
{
455
  bfd_default_set_arch_mach (abfd, bfd_arch_xc16x,
456
                             elf32_xc16x_mach (elf_elfheader (abfd)->e_flags));
457
  return TRUE;
458
}
459
 
460
 
461
#define ELF_ARCH                bfd_arch_xc16x
462
#define ELF_MACHINE_CODE        EM_XC16X
463
#define ELF_MAXPAGESIZE         0x100
464
 
465
#define TARGET_LITTLE_SYM       bfd_elf32_xc16x_vec
466
#define TARGET_LITTLE_NAME      "elf32-xc16x"
467
#define elf_backend_final_write_processing      elf32_xc16x_final_write_processing
468
#define elf_backend_object_p            elf32_xc16x_object_p
469
#define elf_backend_can_gc_sections     1
470
#define bfd_elf32_bfd_reloc_type_lookup xc16x_reloc_type_lookup
471
#define bfd_elf32_bfd_reloc_name_lookup xc16x_reloc_name_lookup
472
#define elf_info_to_howto               elf32_xc16x_info_to_howto
473
#define elf_info_to_howto_rel           elf32_xc16x_info_to_howto
474
#define elf_backend_relocate_section    elf32_xc16x_relocate_section
475
#define elf_backend_rela_normal         1
476
 
477
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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