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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [bfd/] [coff-tic80.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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