~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/bfd/coff-tic4x.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* BFD back-end for TMS320C4X coff binaries.
 
2
   Copyright 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2005, 2007,
 
3
   2008, 2012  Free Software Foundation, Inc.
 
4
 
 
5
   Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz)
 
6
 
 
7
   This file is part of BFD, the Binary File Descriptor library.
 
8
 
 
9
   This program is free software; you can redistribute it and/or modify
 
10
   it under the terms of the GNU General Public License as published by
 
11
   the Free Software Foundation; either version 3 of the License, or
 
12
   (at your option) any later version.
 
13
 
 
14
   This program is distributed in the hope that it will be useful,
 
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
   GNU General Public License for more details.
 
18
 
 
19
   You should have received a copy of the GNU General Public License
 
20
   along with this program; if not, write to the Free Software
 
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
 
22
   02110-1301, USA.  */
 
23
 
 
24
#include "sysdep.h"
 
25
#include "bfd.h"
 
26
#include "libbfd.h"
 
27
#include "bfdlink.h"
 
28
#include "coff/tic4x.h"
 
29
#include "coff/internal.h"
 
30
#include "libcoff.h"
 
31
 
 
32
#undef  F_LSYMS
 
33
#define F_LSYMS         F_LSYMS_TICOFF
 
34
 
 
35
static reloc_howto_type *
 
36
coff_tic4x_rtype_to_howto (bfd *, asection *, struct internal_reloc *,
 
37
                           struct coff_link_hash_entry *,
 
38
                           struct internal_syment *,  bfd_vma *);
 
39
static void
 
40
tic4x_reloc_processing (arelent *, struct internal_reloc *,
 
41
                        asymbol **, bfd *, asection *);
 
42
 
 
43
/* Replace the stock _bfd_coff_is_local_label_name to recognize TI COFF local
 
44
   labels.  */
 
45
static bfd_boolean
 
46
ticoff_bfd_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
 
47
                                const char *name)
 
48
{
 
49
  if (TICOFF_LOCAL_LABEL_P(name))
 
50
    return TRUE;
 
51
  return FALSE;
 
52
}
 
53
 
 
54
#define coff_bfd_is_local_label_name ticoff_bfd_is_local_label_name
 
55
 
 
56
#define RELOC_PROCESSING(RELENT,RELOC,SYMS,ABFD,SECT)\
 
57
 tic4x_reloc_processing (RELENT,RELOC,SYMS,ABFD,SECT)
 
58
 
 
59
/* Customize coffcode.h; the default coff_ functions are set up to use
 
60
   COFF2; coff_bad_format_hook uses BADMAG, so set that for COFF2.
 
61
   The COFF1 and COFF0 vectors use custom _bad_format_hook procs
 
62
   instead of setting BADMAG.  */
 
63
#define BADMAG(x) COFF2_BADMAG(x)
 
64
 
 
65
#undef  coff_rtype_to_howto
 
66
#define coff_rtype_to_howto     coff_tic4x_rtype_to_howto
 
67
 
 
68
#ifndef bfd_pe_print_pdata
 
69
#define bfd_pe_print_pdata      NULL
 
70
#endif
 
71
 
 
72
#include "coffcode.h"
 
73
 
 
74
static bfd_reloc_status_type
 
75
tic4x_relocation (bfd *abfd ATTRIBUTE_UNUSED,
 
76
                  arelent *reloc_entry,
 
77
                  asymbol *symbol ATTRIBUTE_UNUSED,
 
78
                  void * data ATTRIBUTE_UNUSED,
 
79
                  asection *input_section,
 
80
                  bfd *output_bfd,
 
81
                  char **error_message ATTRIBUTE_UNUSED)
 
82
{
 
83
  if (output_bfd != (bfd *) NULL)
 
84
    {
 
85
      /* This is a partial relocation, and we want to apply the
 
86
         relocation to the reloc entry rather than the raw data.
 
87
         Modify the reloc inplace to reflect what we now know.  */
 
88
      reloc_entry->address += input_section->output_offset;
 
89
      return bfd_reloc_ok;
 
90
    }
 
91
  return bfd_reloc_continue;
 
92
}
 
93
 
 
94
reloc_howto_type tic4x_howto_table[] =
 
95
{
 
96
    HOWTO(R_RELWORD,     0,  2, 16, FALSE, 0, complain_overflow_signed,   tic4x_relocation, "RELWORD",   TRUE, 0x0000ffff, 0x0000ffff, FALSE),
 
97
    HOWTO(R_REL24,       0,  2, 24, FALSE, 0, complain_overflow_bitfield, tic4x_relocation, "REL24",     TRUE, 0x00ffffff, 0x00ffffff, FALSE),
 
98
    HOWTO(R_RELLONG,     0,  2, 32, FALSE, 0, complain_overflow_dont,     tic4x_relocation, "RELLONG",   TRUE, 0xffffffff, 0xffffffff, FALSE),
 
99
    HOWTO(R_PCRWORD,     0,  2, 16, TRUE,  0, complain_overflow_signed,   tic4x_relocation, "PCRWORD",   TRUE, 0x0000ffff, 0x0000ffff, FALSE),
 
100
    HOWTO(R_PCR24,       0,  2, 24, TRUE,  0, complain_overflow_signed,   tic4x_relocation, "PCR24",     TRUE, 0x00ffffff, 0x00ffffff, FALSE),
 
101
    HOWTO(R_PARTLS16,    0,  2, 16, FALSE, 0, complain_overflow_dont,     tic4x_relocation, "PARTLS16",  TRUE, 0x0000ffff, 0x0000ffff, FALSE),
 
102
    HOWTO(R_PARTMS8,    16,  2, 16, FALSE, 0, complain_overflow_dont,     tic4x_relocation, "PARTMS8",   TRUE, 0x0000ffff, 0x0000ffff, FALSE),
 
103
    HOWTO(R_RELWORD,     0,  2, 16, FALSE, 0, complain_overflow_signed,   tic4x_relocation, "ARELWORD",  TRUE, 0x0000ffff, 0x0000ffff, FALSE),
 
104
    HOWTO(R_REL24,       0,  2, 24, FALSE, 0, complain_overflow_signed,   tic4x_relocation, "AREL24",    TRUE, 0x00ffffff, 0x00ffffff, FALSE),
 
105
    HOWTO(R_RELLONG,     0,  2, 32, FALSE, 0, complain_overflow_signed,   tic4x_relocation, "ARELLONG",  TRUE, 0xffffffff, 0xffffffff, FALSE),
 
106
    HOWTO(R_PCRWORD,     0,  2, 16, TRUE,  0, complain_overflow_signed,   tic4x_relocation, "APCRWORD",  TRUE, 0x0000ffff, 0x0000ffff, FALSE),
 
107
    HOWTO(R_PCR24,       0,  2, 24, TRUE,  0, complain_overflow_signed,   tic4x_relocation, "APCR24",    TRUE, 0x00ffffff, 0x00ffffff, FALSE),
 
108
    HOWTO(R_PARTLS16,    0,  2, 16, FALSE, 0, complain_overflow_dont,     tic4x_relocation, "APARTLS16", TRUE, 0x0000ffff, 0x0000ffff, FALSE),
 
109
    HOWTO(R_PARTMS8,    16,  2, 16, FALSE, 0, complain_overflow_dont,     tic4x_relocation, "APARTMS8",  TRUE, 0x0000ffff, 0x0000ffff, FALSE),
 
110
};
 
111
#define HOWTO_SIZE (sizeof(tic4x_howto_table) / sizeof(tic4x_howto_table[0]))
 
112
 
 
113
#undef coff_bfd_reloc_type_lookup
 
114
#define coff_bfd_reloc_type_lookup tic4x_coff_reloc_type_lookup
 
115
#undef coff_bfd_reloc_name_lookup
 
116
#define coff_bfd_reloc_name_lookup tic4x_coff_reloc_name_lookup
 
117
 
 
118
/* For the case statement use the code values used tc_gen_reloc (defined in
 
119
   bfd/reloc.c) to map to the howto table entries.  */
 
120
 
 
121
static reloc_howto_type *
 
122
tic4x_coff_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
123
                              bfd_reloc_code_real_type code)
 
124
{
 
125
  unsigned int type;
 
126
  unsigned int i;
 
127
 
 
128
  switch (code)
 
129
    {
 
130
    case BFD_RELOC_32:          type = R_RELLONG; break;
 
131
    case BFD_RELOC_24:          type = R_REL24; break;
 
132
    case BFD_RELOC_16:          type = R_RELWORD; break;
 
133
    case BFD_RELOC_24_PCREL:    type = R_PCR24; break;
 
134
    case BFD_RELOC_16_PCREL:    type = R_PCRWORD; break;
 
135
    case BFD_RELOC_HI16:        type = R_PARTMS8; break;
 
136
    case BFD_RELOC_LO16:        type = R_PARTLS16; break;
 
137
    default:
 
138
      return NULL;
 
139
    }
 
140
 
 
141
  for (i = 0; i < HOWTO_SIZE; i++)
 
142
    {
 
143
      if (tic4x_howto_table[i].type == type)
 
144
        return tic4x_howto_table + i;
 
145
    }
 
146
  return NULL;
 
147
}
 
148
 
 
149
static reloc_howto_type *
 
150
tic4x_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
151
                              const char *r_name)
 
152
{
 
153
  unsigned int i;
 
154
 
 
155
  for (i = 0;
 
156
       i < sizeof (tic4x_howto_table) / sizeof (tic4x_howto_table[0]);
 
157
       i++)
 
158
    if (tic4x_howto_table[i].name != NULL
 
159
        && strcasecmp (tic4x_howto_table[i].name, r_name) == 0)
 
160
      return &tic4x_howto_table[i];
 
161
 
 
162
  return NULL;
 
163
}
 
164
 
 
165
/* Code to turn a r_type into a howto ptr, uses the above howto table.
 
166
   Called after some initial checking by the tic4x_rtype_to_howto fn
 
167
   below.  */
 
168
static void
 
169
tic4x_lookup_howto (arelent *internal,
 
170
                    struct internal_reloc *dst)
 
171
{
 
172
  unsigned int i;
 
173
  int bank = (dst->r_symndx == -1) ? HOWTO_BANK : 0;
 
174
 
 
175
  for (i = 0; i < HOWTO_SIZE; i++)
 
176
    {
 
177
      if (tic4x_howto_table[i].type == dst->r_type)
 
178
        {
 
179
          internal->howto = tic4x_howto_table + i + bank;
 
180
          return;
 
181
        }
 
182
    }
 
183
 
 
184
  (*_bfd_error_handler) (_("Unrecognized reloc type 0x%x"),
 
185
                         (unsigned int) dst->r_type);
 
186
  abort();
 
187
}
 
188
 
 
189
static reloc_howto_type *
 
190
coff_tic4x_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
 
191
                           asection *sec,
 
192
                           struct internal_reloc *rel,
 
193
                           struct coff_link_hash_entry *h ATTRIBUTE_UNUSED,
 
194
                           struct internal_syment *sym ATTRIBUTE_UNUSED,
 
195
                           bfd_vma *addendp)
 
196
{
 
197
  arelent genrel;
 
198
 
 
199
  if (rel->r_symndx == -1 && addendp != NULL)
 
200
    /* This is a TI "internal relocation", which means that the relocation
 
201
       amount is the amount by which the current section is being relocated
 
202
       in the output section.  */
 
203
    *addendp = (sec->output_section->vma + sec->output_offset) - sec->vma;
 
204
 
 
205
  tic4x_lookup_howto (&genrel, rel);
 
206
 
 
207
  return genrel.howto;
 
208
}
 
209
 
 
210
 
 
211
static void
 
212
tic4x_reloc_processing (arelent *relent,
 
213
                        struct internal_reloc *reloc,
 
214
                        asymbol **symbols,
 
215
                        bfd *abfd,
 
216
                        asection *section)
 
217
{
 
218
  asymbol *ptr;
 
219
 
 
220
  relent->address = reloc->r_vaddr;
 
221
 
 
222
  if (reloc->r_symndx != -1)
 
223
    {
 
224
      if (reloc->r_symndx < 0 || reloc->r_symndx >= obj_conv_table_size (abfd))
 
225
        {
 
226
          (*_bfd_error_handler)
 
227
            (_("%s: warning: illegal symbol index %ld in relocs"),
 
228
             bfd_get_filename (abfd), reloc->r_symndx);
 
229
          relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
 
230
          ptr = NULL;
 
231
        }
 
232
      else
 
233
        {
 
234
          relent->sym_ptr_ptr = (symbols
 
235
                                 + obj_convert (abfd)[reloc->r_symndx]);
 
236
          ptr = *(relent->sym_ptr_ptr);
 
237
        }
 
238
    }
 
239
  else
 
240
    {
 
241
      relent->sym_ptr_ptr = section->symbol_ptr_ptr;
 
242
      ptr = *(relent->sym_ptr_ptr);
 
243
    }
 
244
 
 
245
  /* The symbols definitions that we have read in have been relocated
 
246
     as if their sections started at 0.  But the offsets refering to
 
247
     the symbols in the raw data have not been modified, so we have to
 
248
     have a negative addend to compensate.
 
249
 
 
250
     Note that symbols which used to be common must be left alone.  */
 
251
 
 
252
  /* Calculate any reloc addend by looking at the symbol.  */
 
253
  CALC_ADDEND (abfd, ptr, *reloc, relent);
 
254
 
 
255
  relent->address -= section->vma;
 
256
  /* !!     relent->section = (asection *) NULL;  */
 
257
 
 
258
  /* Fill in the relent->howto field from reloc->r_type.  */
 
259
  tic4x_lookup_howto (relent, reloc);
 
260
}
 
261
 
 
262
 
 
263
/* TI COFF v0, DOS tools (little-endian headers).  */
 
264
CREATE_LITTLE_COFF_TARGET_VEC(tic4x_coff0_vec, "coff0-tic4x",
 
265
                              HAS_LOAD_PAGE, SEC_CODE | SEC_READONLY, '_',
 
266
                              NULL, &ticoff0_swap_table);
 
267
 
 
268
/* TI COFF v0, SPARC tools (big-endian headers).  */
 
269
CREATE_BIGHDR_COFF_TARGET_VEC(tic4x_coff0_beh_vec, "coff0-beh-tic4x",
 
270
                              HAS_LOAD_PAGE, SEC_CODE | SEC_READONLY, '_',
 
271
                              &tic4x_coff0_vec, &ticoff0_swap_table);
 
272
 
 
273
/* TI COFF v1, DOS tools (little-endian headers).  */
 
274
CREATE_LITTLE_COFF_TARGET_VEC(tic4x_coff1_vec, "coff1-tic4x",
 
275
                              HAS_LOAD_PAGE, SEC_CODE | SEC_READONLY, '_',
 
276
                              &tic4x_coff0_beh_vec, &ticoff1_swap_table);
 
277
 
 
278
/* TI COFF v1, SPARC tools (big-endian headers).  */
 
279
CREATE_BIGHDR_COFF_TARGET_VEC(tic4x_coff1_beh_vec, "coff1-beh-tic4x",
 
280
                              HAS_LOAD_PAGE, SEC_CODE | SEC_READONLY, '_',
 
281
                              &tic4x_coff1_vec, &ticoff1_swap_table);
 
282
 
 
283
/* TI COFF v2, TI DOS tools output (little-endian headers).  */
 
284
CREATE_LITTLE_COFF_TARGET_VEC(tic4x_coff2_vec, "coff2-tic4x",
 
285
                              HAS_LOAD_PAGE, SEC_CODE | SEC_READONLY, '_',
 
286
                              &tic4x_coff1_beh_vec, COFF_SWAP_TABLE);
 
287
 
 
288
/* TI COFF v2, TI SPARC tools output (big-endian headers).  */
 
289
CREATE_BIGHDR_COFF_TARGET_VEC(tic4x_coff2_beh_vec, "coff2-beh-tic4x",
 
290
                              HAS_LOAD_PAGE, SEC_CODE | SEC_READONLY, '_',
 
291
                              &tic4x_coff2_vec, COFF_SWAP_TABLE);