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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [bfd/] [coff-tic80.c] - Blame information for rev 843

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

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

powered by: WebSVN 2.1.0

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