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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [bfd/] [coff-tic80.c] - Blame information for rev 578

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

Line No. Rev Author Line
1 578 markom
/* BFD back-end for Texas Instruments TMS320C80 Multimedia Video Processor (MVP).
2
   Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
3
 
4
   Written by Fred Fish (fnf@cygnus.com)
5
 
6
   There is nothing new under the sun. This file draws a lot on other
7
   coff files.
8
 
9
This file is part of BFD, the Binary File Descriptor library.
10
 
11
This program is free software; you can redistribute it and/or modify
12
it under the terms of the GNU General Public License as published by
13
the Free Software Foundation; either version 2 of the License, or
14
(at your option) any later version.
15
 
16
This program is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
GNU General Public License for more details.
20
 
21
You should have received a copy of the GNU General Public License
22
along with this program; if not, write to the Free Software
23
Foundation, 59 Temple Place - Suite 330,
24
Boston, MA 02111-1307, USA.  */
25
 
26
#include "bfd.h"
27
#include "bfdlink.h"
28
#include "sysdep.h"
29
#include "libbfd.h"
30
#include "coff/tic80.h"
31
#include "coff/internal.h"
32
#include "libcoff.h"
33
 
34
#define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (2)
35
#define COFF_ALIGN_IN_SECTION_HEADER 1
36
#define COFF_ALIGN_IN_SFLAGS 1
37
 
38
#define GET_SCNHDR_FLAGS bfd_h_get_16
39
#define PUT_SCNHDR_FLAGS bfd_h_put_16
40
 
41
static void rtype2howto
42
  PARAMS ((arelent *cache_ptr, struct internal_reloc *dst));
43
static bfd_reloc_status_type ppbase_reloc
44
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
45
static bfd_reloc_status_type glob15_reloc
46
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
47
static bfd_reloc_status_type glob16_reloc
48
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
49
static bfd_reloc_status_type local16_reloc
50
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
51
static boolean coff_tic80_relocate_section
52
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
53
           struct internal_reloc *, struct internal_syment *, asection **));
54
 
55
static reloc_howto_type tic80_howto_table[] =
56
{
57
 
58
  HOWTO (R_RELLONG,                     /* type */
59
         0,                              /* rightshift */
60
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
61
         32,                            /* bitsize */
62
         false,                         /* pc_relative */
63
         0,                              /* bitpos */
64
         complain_overflow_bitfield,    /* complain_on_overflow */
65
         NULL,                          /* special_function */
66
         "RELLONG",                     /* name */
67
         true,                          /* partial_inplace */
68
         0xffffffff,                    /* src_mask */
69
         0xffffffff,                    /* dst_mask */
70
         false),                        /* pcrel_offset */
71
 
72
  HOWTO (R_MPPCR,                       /* type */
73
         2,                             /* rightshift */
74
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
75
         32,                            /* bitsize */
76
         true,                          /* pc_relative */
77
         0,                              /* bitpos */
78
         complain_overflow_signed,      /* complain_on_overflow */
79
         NULL,                          /* special_function */
80
         "MPPCR",                       /* name */
81
         true,                          /* partial_inplace */
82
         0xffffffff,                    /* src_mask */
83
         0xffffffff,                    /* dst_mask */
84
         true),                         /* pcrel_offset */
85
 
86
  HOWTO (R_ABS,                         /* type */
87
         0,                              /* rightshift */
88
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
89
         32,                            /* bitsize */
90
         false,                         /* pc_relative */
91
         0,                              /* bitpos */
92
         complain_overflow_bitfield,    /* complain_on_overflow */
93
         NULL,                          /* special_function */
94
         "ABS",                         /* name */
95
         true,                          /* partial_inplace */
96
         0xffffffff,                    /* src_mask */
97
         0xffffffff,                    /* dst_mask */
98
         false),                                /* pcrel_offset */
99
 
100
  HOWTO (R_PPBASE,                      /* type */
101
         0,                              /* rightshift */
102
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
103
         32,                            /* bitsize */
104
         false,                         /* pc_relative */
105
         0,                              /* bitpos */
106
         complain_overflow_dont,        /* complain_on_overflow */
107
         ppbase_reloc,                  /* special_function */
108
         "PPBASE",                      /* name */
109
         true,                          /* partial_inplace */
110
         0xffffffff,                    /* src_mask */
111
         0xffffffff,                    /* dst_mask */
112
         false),                        /* pcrel_offset */
113
 
114
  HOWTO (R_PPLBASE,                     /* type */
115
         0,                              /* rightshift */
116
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
117
         32,                            /* bitsize */
118
         false,                         /* pc_relative */
119
         0,                              /* bitpos */
120
         complain_overflow_dont,        /* complain_on_overflow */
121
         ppbase_reloc,                  /* special_function */
122
         "PPLBASE",                     /* name */
123
         true,                          /* partial_inplace */
124
         0xffffffff,                    /* src_mask */
125
         0xffffffff,                    /* dst_mask */
126
         false),                        /* pcrel_offset */
127
 
128
  HOWTO (R_PP15,                        /* type */
129
         0,                              /* rightshift */
130
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
131
         15,                            /* bitsize */
132
         false,                         /* pc_relative */
133
         6,                             /* bitpos */
134
         complain_overflow_dont,        /* complain_on_overflow */
135
         glob15_reloc,                  /* special_function */
136
         "PP15",                        /* name */
137
         true,                          /* partial_inplace */
138
         0x1ffc0,                       /* src_mask */
139
         0x1ffc0,                       /* dst_mask */
140
         false),                        /* pcrel_offset */
141
 
142
  HOWTO (R_PP15W,                       /* type */
143
         2,                             /* rightshift */
144
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
145
         15,                            /* bitsize */
146
         false,                         /* pc_relative */
147
         6,                             /* bitpos */
148
         complain_overflow_dont,        /* complain_on_overflow */
149
         glob15_reloc,                  /* special_function */
150
         "PP15W",                       /* name */
151
         true,                          /* partial_inplace */
152
         0x1ffc0,                       /* src_mask */
153
         0x1ffc0,                       /* dst_mask */
154
         false),                        /* pcrel_offset */
155
 
156
  HOWTO (R_PP15H,                       /* type */
157
         1,                             /* rightshift */
158
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
159
         15,                            /* bitsize */
160
         false,                         /* pc_relative */
161
         6,                             /* bitpos */
162
         complain_overflow_dont,        /* complain_on_overflow */
163
         glob15_reloc,                  /* special_function */
164
         "PP15H",                       /* name */
165
         true,                          /* partial_inplace */
166
         0x1ffc0,                       /* src_mask */
167
         0x1ffc0,                       /* dst_mask */
168
         false),                        /* pcrel_offset */
169
 
170
  HOWTO (R_PP16B,                       /* type */
171
         0,                              /* rightshift */
172
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
173
         16,                            /* bitsize */
174
         false,                         /* pc_relative */
175
         6,                             /* bitpos */
176
         complain_overflow_dont,        /* complain_on_overflow */
177
         glob16_reloc,                  /* special_function */
178
         "PP16B",                       /* name */
179
         true,                          /* partial_inplace */
180
         0x3ffc0,                       /* src_mask */
181
         0x3ffc0,                       /* dst_mask */
182
         false),                        /* pcrel_offset */
183
 
184
  HOWTO (R_PPL15,                       /* type */
185
         0,                              /* rightshift */
186
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
187
         15,                            /* bitsize */
188
         false,                         /* pc_relative */
189
         0,                              /* bitpos */
190
         complain_overflow_dont,        /* complain_on_overflow */
191
         NULL,                          /* special_function */
192
         "PPL15",                       /* name */
193
         true,                          /* partial_inplace */
194
         0x7fff,                        /* src_mask */
195
         0x7fff,                        /* dst_mask */
196
         false),                        /* pcrel_offset */
197
 
198
  HOWTO (R_PPL15W,                      /* type */
199
         2,                             /* rightshift */
200
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
201
         15,                            /* bitsize */
202
         false,                         /* pc_relative */
203
         0,                              /* bitpos */
204
         complain_overflow_dont,        /* complain_on_overflow */
205
         NULL,                          /* special_function */
206
         "PPL15W",                      /* name */
207
         true,                          /* partial_inplace */
208
         0x7fff,                        /* src_mask */
209
         0x7fff,                        /* dst_mask */
210
         false),                        /* pcrel_offset */
211
 
212
  HOWTO (R_PPL15H,                      /* type */
213
         1,                             /* rightshift */
214
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
215
         15,                            /* bitsize */
216
         false,                         /* pc_relative */
217
         0,                              /* bitpos */
218
         complain_overflow_dont,        /* complain_on_overflow */
219
         NULL,                          /* special_function */
220
         "PPL15H",                      /* name */
221
         true,                          /* partial_inplace */
222
         0x7fff,                        /* src_mask */
223
         0x7fff,                        /* dst_mask */
224
         false),                        /* pcrel_offset */
225
 
226
  HOWTO (R_PPL16B,                      /* type */
227
         0,                              /* rightshift */
228
         2,                             /* size (0 = byte, 1 = short, 2 = long) */
229
         16,                            /* bitsize */
230
         false,                         /* pc_relative */
231
         0,                              /* bitpos */
232
         complain_overflow_dont,        /* complain_on_overflow */
233
         local16_reloc,                 /* special_function */
234
         "PPL16B",                      /* name */
235
         true,                          /* partial_inplace */
236
         0xffff,                        /* src_mask */
237
         0xffff,                        /* dst_mask */
238
         false),                        /* pcrel_offset */
239
 
240
  HOWTO (R_PPN15,                       /* type */
241
         0,                              /* rightshift */
242
         -2,                            /* size (0 = byte, 1 = short, 2 = long) */
243
         15,                            /* bitsize */
244
         false,                         /* pc_relative */
245
         6,                             /* bitpos */
246
         complain_overflow_dont,        /* complain_on_overflow */
247
         glob15_reloc,                  /* special_function */
248
         "PPN15",                       /* name */
249
         true,                          /* partial_inplace */
250
         0x1ffc0,                       /* src_mask */
251
         0x1ffc0,                       /* dst_mask */
252
         false),                        /* pcrel_offset */
253
 
254
  HOWTO (R_PPN15W,                      /* type */
255
         2,                             /* rightshift */
256
         -2,                            /* size (0 = byte, 1 = short, 2 = long) */
257
         15,                            /* bitsize */
258
         false,                         /* pc_relative */
259
         6,                             /* bitpos */
260
         complain_overflow_dont,        /* complain_on_overflow */
261
         glob15_reloc,                  /* special_function */
262
         "PPN15W",                      /* name */
263
         true,                          /* partial_inplace */
264
         0x1ffc0,                       /* src_mask */
265
         0x1ffc0,                       /* dst_mask */
266
         false),                        /* pcrel_offset */
267
 
268
  HOWTO (R_PPN15H,                      /* type */
269
         1,                             /* rightshift */
270
         -2,                            /* size (0 = byte, 1 = short, 2 = long) */
271
         15,                            /* bitsize */
272
         false,                         /* pc_relative */
273
         6,                             /* bitpos */
274
         complain_overflow_dont,        /* complain_on_overflow */
275
         glob15_reloc,                  /* special_function */
276
         "PPN15H",                      /* name */
277
         true,                          /* partial_inplace */
278
         0x1ffc0,                       /* src_mask */
279
         0x1ffc0,                       /* dst_mask */
280
         false),                        /* pcrel_offset */
281
 
282
  HOWTO (R_PPN16B,                      /* type */
283
         0,                              /* rightshift */
284
         -2,                            /* size (0 = byte, 1 = short, 2 = long) */
285
         16,                            /* bitsize */
286
         false,                         /* pc_relative */
287
         6,                             /* bitpos */
288
         complain_overflow_dont,        /* complain_on_overflow */
289
         glob16_reloc,                  /* special_function */
290
         "PPN16B",                      /* name */
291
         true,                          /* partial_inplace */
292
         0x3ffc0,                       /* src_mask */
293
         0x3ffc0,                       /* dst_mask */
294
         false),                        /* pcrel_offset */
295
 
296
  HOWTO (R_PPLN15,                      /* type */
297
         0,                              /* rightshift */
298
         -2,                            /* size (0 = byte, 1 = short, 2 = long) */
299
         15,                            /* bitsize */
300
         false,                         /* pc_relative */
301
         0,                              /* bitpos */
302
         complain_overflow_dont,        /* complain_on_overflow */
303
         NULL,                          /* special_function */
304
         "PPLN15",                      /* name */
305
         true,                          /* partial_inplace */
306
         0x7fff,                        /* src_mask */
307
         0x7fff,                        /* dst_mask */
308
         false),                        /* pcrel_offset */
309
 
310
  HOWTO (R_PPLN15W,                     /* type */
311
         2,                             /* rightshift */
312
         -2,                            /* size (0 = byte, 1 = short, 2 = long) */
313
         15,                            /* bitsize */
314
         false,                         /* pc_relative */
315
         0,                              /* bitpos */
316
         complain_overflow_dont,        /* complain_on_overflow */
317
         NULL,                          /* special_function */
318
         "PPLN15W",                     /* name */
319
         true,                          /* partial_inplace */
320
         0x7fff,                        /* src_mask */
321
         0x7fff,                        /* dst_mask */
322
         false),                        /* pcrel_offset */
323
 
324
  HOWTO (R_PPLN15H,                     /* type */
325
         1,                             /* rightshift */
326
         -2,                            /* size (0 = byte, 1 = short, 2 = long) */
327
         15,                            /* bitsize */
328
         false,                         /* pc_relative */
329
         0,                              /* bitpos */
330
         complain_overflow_dont,        /* complain_on_overflow */
331
         NULL,                          /* special_function */
332
         "PPLN15H",                     /* name */
333
         true,                          /* partial_inplace */
334
         0x7fff,                        /* src_mask */
335
         0x7fff,                        /* dst_mask */
336
         false),                        /* pcrel_offset */
337
 
338
  HOWTO (R_PPLN16B,                     /* type */
339
         0,                              /* rightshift */
340
         -2,                            /* size (0 = byte, 1 = short, 2 = long) */
341
         15,                            /* bitsize */
342
         false,                         /* pc_relative */
343
         0,                              /* bitpos */
344
         complain_overflow_dont,        /* complain_on_overflow */
345
         local16_reloc,                 /* special_function */
346
         "PPLN16B",                     /* name */
347
         true,                          /* partial_inplace */
348
         0xffff,                        /* src_mask */
349
         0xffff,                        /* dst_mask */
350
         false)                         /* pcrel_offset */
351
};
352
 
353
/* Special relocation functions, used when the output file is not
354
   itself a COFF TIc80 file.  */
355
 
356
/* This special function is used for the base address type
357
   relocations.  */
358
 
359
static bfd_reloc_status_type
360
ppbase_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
361
              error_message)
362
     bfd *abfd ATTRIBUTE_UNUSED;
363
     arelent *reloc_entry ATTRIBUTE_UNUSED;
364
     asymbol *symbol_in ATTRIBUTE_UNUSED;
365
     PTR data ATTRIBUTE_UNUSED;
366
     asection *input_section ATTRIBUTE_UNUSED;
367
     bfd *output_bfd ATTRIBUTE_UNUSED;
368
     char **error_message ATTRIBUTE_UNUSED;
369
{
370
  /* FIXME.  */
371
  abort ();
372
}
373
 
374
/* This special function is used for the global 15 bit relocations.  */
375
 
376
static bfd_reloc_status_type
377
glob15_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
378
              error_message)
379
     bfd *abfd ATTRIBUTE_UNUSED;
380
     arelent *reloc_entry ATTRIBUTE_UNUSED;
381
     asymbol *symbol_in ATTRIBUTE_UNUSED;
382
     PTR data ATTRIBUTE_UNUSED;
383
     asection *input_section ATTRIBUTE_UNUSED;
384
     bfd *output_bfd ATTRIBUTE_UNUSED;
385
     char **error_message ATTRIBUTE_UNUSED;
386
{
387
  /* FIXME.  */
388
  abort ();
389
}
390
 
391
/* This special function is used for the global 16 bit relocations.  */
392
 
393
static bfd_reloc_status_type
394
glob16_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
395
              error_message)
396
     bfd *abfd ATTRIBUTE_UNUSED;
397
     arelent *reloc_entry ATTRIBUTE_UNUSED;
398
     asymbol *symbol_in ATTRIBUTE_UNUSED;
399
     PTR data ATTRIBUTE_UNUSED;
400
     asection *input_section ATTRIBUTE_UNUSED;
401
     bfd *output_bfd ATTRIBUTE_UNUSED;
402
     char **error_message ATTRIBUTE_UNUSED;
403
{
404
  /* FIXME.  */
405
  abort ();
406
}
407
 
408
/* This special function is used for the local 16 bit relocations.  */
409
 
410
static bfd_reloc_status_type
411
local16_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
412
              error_message)
413
     bfd *abfd ATTRIBUTE_UNUSED;
414
     arelent *reloc_entry ATTRIBUTE_UNUSED;
415
     asymbol *symbol_in ATTRIBUTE_UNUSED;
416
     PTR data ATTRIBUTE_UNUSED;
417
     asection *input_section ATTRIBUTE_UNUSED;
418
     bfd *output_bfd ATTRIBUTE_UNUSED;
419
     char **error_message ATTRIBUTE_UNUSED;
420
{
421
  /* FIXME.  */
422
  abort ();
423
}
424
 
425
/* Code to turn an external r_type into a pointer to an entry in the howto_table.
426
   If passed an r_type we don't recognize the abort rather than silently failing
427
   to generate an output file.  */
428
 
429
static void
430
rtype2howto (cache_ptr, dst)
431
     arelent *cache_ptr;
432
     struct internal_reloc *dst;
433
{
434
  unsigned int i;
435
 
436
  for (i = 0; i < sizeof tic80_howto_table / sizeof tic80_howto_table[0]; i++)
437
    {
438
      if (tic80_howto_table[i].type == dst->r_type)
439
        {
440
          cache_ptr->howto = tic80_howto_table + i;
441
          return;
442
        }
443
    }
444
 
445
  (*_bfd_error_handler) (_("Unrecognized reloc type 0x%x"),
446
                         (unsigned int) dst->r_type);
447
  cache_ptr->howto = tic80_howto_table + 0;
448
}
449
 
450
#define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
451
#define coff_rtype_to_howto coff_tic80_rtype_to_howto
452
 
453
static reloc_howto_type *
454
coff_tic80_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
455
     bfd *abfd ATTRIBUTE_UNUSED;
456
     asection *sec;
457
     struct internal_reloc *rel;
458
     struct coff_link_hash_entry *h ATTRIBUTE_UNUSED;
459
     struct internal_syment *sym ATTRIBUTE_UNUSED;
460
     bfd_vma *addendp;
461
{
462
  arelent genrel;
463
 
464
  if (rel -> r_symndx == -1 && addendp != NULL)
465
    {
466
      /* This is a TI "internal relocation", which means that the relocation
467
         amount is the amount by which the current section is being relocated
468
         in the output section.  */
469
      *addendp = (sec -> output_section -> vma + sec -> output_offset) - sec -> vma;
470
    }
471
  RTYPE2HOWTO (&genrel, rel);
472
  return genrel.howto;
473
}
474
 
475
#ifndef BADMAG
476
#define BADMAG(x) TIC80BADMAG(x)
477
#endif
478
 
479
#define coff_relocate_section coff_tic80_relocate_section
480
 
481
/* We need a special relocation routine to handle the PP relocs.  Most
482
   of this is a copy of _bfd_coff_generic_relocate_section.  */
483
 
484
static boolean
485
coff_tic80_relocate_section (output_bfd, info, input_bfd,
486
                             input_section, contents, relocs, syms,
487
                             sections)
488
     bfd *output_bfd;
489
     struct bfd_link_info *info;
490
     bfd *input_bfd;
491
     asection *input_section;
492
     bfd_byte *contents;
493
     struct internal_reloc *relocs;
494
     struct internal_syment *syms;
495
     asection **sections;
496
{
497
  struct internal_reloc *rel;
498
  struct internal_reloc *relend;
499
 
500
  rel = relocs;
501
  relend = rel + input_section->reloc_count;
502
  for (; rel < relend; rel++)
503
    {
504
      long symndx;
505
      struct coff_link_hash_entry *h;
506
      struct internal_syment *sym;
507
      bfd_vma addend;
508
      bfd_vma val;
509
      reloc_howto_type *howto;
510
      bfd_reloc_status_type rstat;
511
      bfd_vma addr;
512
 
513
      symndx = rel->r_symndx;
514
 
515
      if (symndx == -1)
516
        {
517
          h = NULL;
518
          sym = NULL;
519
        }
520
      else
521
        {
522
          h = obj_coff_sym_hashes (input_bfd)[symndx];
523
          sym = syms + symndx;
524
        }
525
 
526
      /* COFF treats common symbols in one of two ways.  Either the
527
         size of the symbol is included in the section contents, or it
528
         is not.  We assume that the size is not included, and force
529
         the rtype_to_howto function to adjust the addend as needed.  */
530
 
531
      if (sym != NULL && sym->n_scnum != 0)
532
        addend = - sym->n_value;
533
      else
534
        addend = 0;
535
 
536
      howto = bfd_coff_rtype_to_howto (input_bfd, input_section, rel, h,
537
                                       sym, &addend);
538
      if (howto == NULL)
539
        return false;
540
 
541
      val = 0;
542
 
543
      if (h == NULL)
544
        {
545
          asection *sec;
546
 
547
          if (symndx == -1)
548
            {
549
              sec = bfd_abs_section_ptr;
550
              val = 0;
551
            }
552
          else
553
            {
554
              sec = sections[symndx];
555
              val = (sec->output_section->vma
556
                     + sec->output_offset
557
                     + sym->n_value);
558
              if (! obj_pe (output_bfd))
559
                val -= sec->vma;
560
            }
561
        }
562
      else
563
        {
564
          if (h->root.type == bfd_link_hash_defined
565
              || h->root.type == bfd_link_hash_defweak)
566
            {
567
              asection *sec;
568
 
569
              sec = h->root.u.def.section;
570
              val = (h->root.u.def.value
571
                     + sec->output_section->vma
572
                     + sec->output_offset);
573
              }
574
 
575
          else if (! info->relocateable)
576
            {
577
              if (! ((*info->callbacks->undefined_symbol)
578
                     (info, h->root.root.string, input_bfd, input_section,
579
                      rel->r_vaddr - input_section->vma, true)))
580
                return false;
581
            }
582
        }
583
 
584
      addr = rel->r_vaddr - input_section->vma;
585
 
586
      /* FIXME: This code assumes little endian, but the PP can
587
         apparently be bi-endian.  I don't know if the bi-endianness
588
         applies to the instruction set or just to the data.  */
589
      switch (howto->type)
590
        {
591
        default:
592
        case R_ABS:
593
        case R_RELLONGX:
594
        case R_PPL15:
595
        case R_PPL15W:
596
        case R_PPL15H:
597
        case R_PPLN15:
598
        case R_PPLN15W:
599
        case R_PPLN15H:
600
          rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
601
                                            contents, addr, val, addend);
602
          break;
603
 
604
        case R_PP15:
605
        case R_PP15W:
606
        case R_PP15H:
607
        case R_PPN15:
608
        case R_PPN15W:
609
        case R_PPN15H:
610
          /* Offset the address so that we can use 4 byte relocations.  */
611
          rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
612
                                            contents + 2, addr, val, addend);
613
          break;
614
 
615
        case R_PP16B:
616
        case R_PPN16B:
617
          {
618
            /* The most significant bit is stored in bit 6.  */
619
            bfd_byte hold;
620
 
621
            hold = contents[addr + 4];
622
            contents[addr + 4] &=~ 0x20;
623
            contents[addr + 4] |= (contents[addr] >> 1) & 0x20;
624
            rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
625
                                              contents + 2, addr,
626
                                              val, addend);
627
            contents[addr] &=~ 0x40;
628
            contents[addr] |= (contents[addr + 4] << 1) & 0x40;
629
            contents[addr + 4] &=~ 0x20;
630
            contents[addr + 4] |= hold & 0x20;
631
            break;
632
          }
633
 
634
        case R_PPL16B:
635
        case R_PPLN16B:
636
          {
637
            /* The most significant bit is stored in bit 28.  */
638
            bfd_byte hold;
639
 
640
            hold = contents[addr + 1];
641
            contents[addr + 1] &=~ 0x80;
642
            contents[addr + 1] |= (contents[addr + 3] << 3) & 0x80;
643
            rstat = _bfd_final_link_relocate (howto, input_bfd, input_section,
644
                                              contents, addr,
645
                                              val, addend);
646
            contents[addr + 3] &= ~0x10;
647
            contents[addr + 3] |= (contents[addr + 1] >> 3) & 0x10;
648
            contents[addr + 1] &=~ 0x80;
649
            contents[addr + 1] |= hold & 0x80;
650
            break;
651
          }
652
 
653
        case R_PPBASE:
654
          /* Parameter RAM is from 0x1000000 to 0x1000800.  */
655
          contents[addr] &=~ 0x3;
656
          if (val >= 0x1000000 && val < 0x1000800)
657
            contents[addr] |= 0x3;
658
          else
659
            contents[addr] |= 0x2;
660
          rstat = bfd_reloc_ok;
661
          break;
662
 
663
        case R_PPLBASE:
664
          /* Parameter RAM is from 0x1000000 to 0x1000800.  */
665
          contents[addr + 2] &= ~0xc0;
666
          if (val >= 0x1000000 && val < 0x1000800)
667
            contents[addr + 2] |= 0xc0;
668
          else
669
            contents[addr + 2] |= 0x80;
670
          rstat = bfd_reloc_ok;
671
          break;
672
        }
673
 
674
      switch (rstat)
675
        {
676
        default:
677
          abort ();
678
        case bfd_reloc_ok:
679
          break;
680
        case bfd_reloc_outofrange:
681
          (*_bfd_error_handler)
682
            (_("%s: bad reloc address 0x%lx in section `%s'"),
683
             bfd_get_filename (input_bfd),
684
             (unsigned long) rel->r_vaddr,
685
             bfd_get_section_name (input_bfd, input_section));
686
          return false;
687
        case bfd_reloc_overflow:
688
          {
689
            const char *name;
690
            char buf[SYMNMLEN + 1];
691
 
692
            if (symndx == -1)
693
              name = "*ABS*";
694
            else if (h != NULL)
695
              name = h->root.root.string;
696
            else
697
              {
698
                name = _bfd_coff_internal_syment_name (input_bfd, sym, buf);
699
                if (name == NULL)
700
                  return false;
701
              }
702
 
703
            if (! ((*info->callbacks->reloc_overflow)
704
                   (info, name, howto->name, (bfd_vma) 0, input_bfd,
705
                    input_section, rel->r_vaddr - input_section->vma)))
706
              return false;
707
          }
708
        }
709
    }
710
  return true;
711
}
712
 
713
#define TIC80COFF 1             /* Customize coffcode.h */
714
#undef C_AUTOARG                /* Clashes with TIc80's C_UEXT */
715
#undef C_LASTENT                /* Clashes with TIc80's C_STATLAB */
716
#include "coffcode.h"
717
 
718
CREATE_LITTLE_COFF_TARGET_VEC (tic80coff_vec, "coff-tic80", D_PAGED, 0, '_', NULL)

powered by: WebSVN 2.1.0

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