~ubuntu-branches/ubuntu/quantal/gclcvs/quantal

« back to all changes in this revision

Viewing changes to binutils/bfd/elf32-dlx.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2004-06-24 15:13:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040624151346-xh0xaaktyyp7aorc
Tags: 2.7.0-26
C_GC_OFFSET is 2 on m68k-linux

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* DLX specific support for 32-bit ELF
 
2
   Copyright 2002 Free Software Foundation, Inc.
 
3
 
 
4
   This file is part of BFD, the Binary File Descriptor library.
 
5
 
 
6
   This program is free software; you can redistribute it and/or modify
 
7
   it under the terms of the GNU General Public License as published by
 
8
   the Free Software Foundation; either version 2 of the License, or
 
9
   (at your option) any later version.
 
10
 
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU General Public License
 
17
   along with this program; if not, write to the Free Software
 
18
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
19
 
 
20
#include "bfd.h"
 
21
#include "sysdep.h"
 
22
#include "libbfd.h"
 
23
#include "elf-bfd.h"
 
24
#include "elf/dlx.h"
 
25
 
 
26
int    set_dlx_skip_hi16_flag PARAMS ((int));
 
27
 
 
28
static boolean elf32_dlx_check_relocs
 
29
  PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *));
 
30
static void elf32_dlx_info_to_howto
 
31
  PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
 
32
static void elf32_dlx_info_to_howto_rel
 
33
  PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
 
34
static bfd_reloc_status_type elf32_dlx_relocate16
 
35
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
 
36
static bfd_reloc_status_type elf32_dlx_relocate26
 
37
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
 
38
static reloc_howto_type *elf32_dlx_reloc_type_lookup
 
39
  PARAMS ((bfd *, bfd_reloc_code_real_type));
 
40
static bfd_reloc_status_type _bfd_dlx_elf_hi16_reloc
 
41
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
 
42
static reloc_howto_type * dlx_rtype_to_howto
 
43
  PARAMS ((unsigned int));
 
44
 
 
45
 
 
46
#define USE_REL 1
 
47
 
 
48
#define bfd_elf32_bfd_reloc_type_lookup elf32_dlx_reloc_type_lookup
 
49
#define elf_info_to_howto               elf32_dlx_info_to_howto
 
50
#define elf_info_to_howto_rel           elf32_dlx_info_to_howto_rel
 
51
#define elf_backend_check_relocs        elf32_dlx_check_relocs
 
52
 
 
53
static reloc_howto_type dlx_elf_howto_table[]=
 
54
  {
 
55
    /* No relocation.  */
 
56
    HOWTO (R_DLX_NONE,            /* type */
 
57
           0,                     /* rightshift */
 
58
           0,                     /* size (0 = byte, 1 = short, 2 = long) */
 
59
           0,                     /* bitsize */
 
60
           false,                 /* pc_relative */
 
61
           0,                     /* bitpos */
 
62
           complain_overflow_dont,/* complain_on_overflow */
 
63
           bfd_elf_generic_reloc, /* special_function */
 
64
           "R_DLX_NONE",          /* name */
 
65
           false,                 /* partial_inplace */
 
66
           0,                     /* src_mask */
 
67
           0,                     /* dst_mask */
 
68
           false),                /* pcrel_offset */
 
69
 
 
70
    /* 8 bit relocation.  */
 
71
    HOWTO (R_DLX_RELOC_8,         /* type */
 
72
           0,                     /* rightshift */
 
73
           0,                     /* size (0 = byte, 1 = short, 2 = long) */
 
74
           8,                     /* bitsize */
 
75
           false,                 /* pc_relative */
 
76
           0,                     /* bitpos */
 
77
           complain_overflow_dont,/* complain_on_overflow */
 
78
           bfd_elf_generic_reloc, /* special_function */
 
79
           "R_DLX_RELOC_8",       /* name */
 
80
           true,                  /* partial_inplace */
 
81
           0xff,                  /* src_mask */
 
82
           0xff,                  /* dst_mask */
 
83
           false),                /* pcrel_offset */
 
84
 
 
85
    /* 16 bit relocation.  */
 
86
    HOWTO (R_DLX_RELOC_16,        /* type */
 
87
           0,                     /* rightshift */
 
88
           1,                     /* size (0 = byte, 1 = short, 2 = long) */
 
89
           16,                    /* bitsize */
 
90
           false,                 /* pc_relative */
 
91
           0,                     /* bitpos */
 
92
           complain_overflow_dont,/* complain_on_overflow */
 
93
           bfd_elf_generic_reloc, /* special_function */
 
94
           "R_DLX_RELOC_16",      /* name */
 
95
           true,                  /* partial_inplace */
 
96
           0xffff,                /* src_mask */
 
97
           0xffff,                /* dst_mask */
 
98
           false),                /* pcrel_offset */
 
99
 
 
100
#if 0
 
101
    /* 26 bit jump address.  */
 
102
    HOWTO (R_DLX_RELOC_26,        /* type */
 
103
           0,                     /* rightshift */
 
104
           2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
105
           26,                    /* bitsize */
 
106
           false,                 /* pc_relative */
 
107
           0,                     /* bitpos */
 
108
           complain_overflow_dont,/* complain_on_overflow */
 
109
           /* This needs complex overflow detection, because the upper four
 
110
              bits must match the PC + 4.  */
 
111
           bfd_elf_generic_reloc, /* special_function */
 
112
           "R_DLX_RELOC_26",      /* name */
 
113
           true,                  /* partial_inplace */
 
114
           0x3ffffff,             /* src_mask */
 
115
           0x3ffffff,             /* dst_mask */
 
116
           false),                /* pcrel_offset */
 
117
#endif
 
118
 
 
119
    /* 32 bit relocation.  */
 
120
    HOWTO (R_DLX_RELOC_32,        /* type */
 
121
           0,                     /* rightshift */
 
122
           2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
123
           32,                    /* bitsize */
 
124
           false,                 /* pc_relative */
 
125
           0,                     /* bitpos */
 
126
           complain_overflow_dont,/* complain_on_overflow */
 
127
           bfd_elf_generic_reloc, /* special_function */
 
128
           "R_DLX_RELOC_32",      /* name */
 
129
           true,                  /* partial_inplace */
 
130
           0xffffffff,            /* src_mask */
 
131
           0xffffffff,            /* dst_mask */
 
132
           false),                /* pcrel_offset */
 
133
 
 
134
    /* GNU extension to record C++ vtable hierarchy */
 
135
    HOWTO (R_DLX_GNU_VTINHERIT,   /* type */
 
136
           0,                     /* rightshift */
 
137
           2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
138
           0,                     /* bitsize */
 
139
           false,                 /* pc_relative */
 
140
           0,                     /* bitpos */
 
141
           complain_overflow_dont,/* complain_on_overflow */
 
142
           NULL,                  /* special_function */
 
143
           "R_DLX_GNU_VTINHERIT", /* name */
 
144
           false,                 /* partial_inplace */
 
145
           0,                     /* src_mask */
 
146
           0,                     /* dst_mask */
 
147
           false),                /* pcrel_offset */
 
148
 
 
149
    /* GNU extension to record C++ vtable member usage */
 
150
    HOWTO (R_DLX_GNU_VTENTRY,     /* type */
 
151
           0,                     /* rightshift */
 
152
           2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
153
           0,                     /* bitsize */
 
154
           false,                 /* pc_relative */
 
155
           0,                     /* bitpos */
 
156
           complain_overflow_dont,/* complain_on_overflow */
 
157
           _bfd_elf_rel_vtable_reloc_fn,/* special_function */
 
158
           "R_DLX_GNU_VTENTRY",   /* name */
 
159
           false,                 /* partial_inplace */
 
160
           0,                     /* src_mask */
 
161
           0,                     /* dst_mask */
 
162
           false)                 /* pcrel_offset */
 
163
  };
 
164
 
 
165
/* 16 bit offset for pc-relative branches.  */
 
166
static reloc_howto_type elf_dlx_gnu_rel16_s2 =
 
167
HOWTO (R_DLX_RELOC_16_PCREL,  /* type */
 
168
       0,                     /* rightshift */
 
169
       1,                     /* size (0 = byte, 1 = short, 2 = long) */
 
170
       16,                    /* bitsize */
 
171
       true,                  /* pc_relative */
 
172
       0,                     /* bitpos */
 
173
       complain_overflow_signed, /* complain_on_overflow */
 
174
       elf32_dlx_relocate16,  /* special_function */
 
175
       "R_DLX_RELOC_16_PCREL",/* name */
 
176
       true,                  /* partial_inplace */
 
177
       0xffff,                /* src_mask */
 
178
       0xffff,                /* dst_mask */
 
179
       true);                 /* pcrel_offset */
 
180
 
 
181
/* 26 bit offset for pc-relative branches.  */
 
182
static reloc_howto_type elf_dlx_gnu_rel26_s2 =
 
183
HOWTO (R_DLX_RELOC_26_PCREL,  /* type */
 
184
       0,                     /* rightshift */
 
185
       2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
186
       26,                    /* bitsize */
 
187
       true,                  /* pc_relative */
 
188
       0,                     /* bitpos */
 
189
       complain_overflow_dont,/* complain_on_overflow */
 
190
       elf32_dlx_relocate26,  /* special_function */
 
191
       "R_DLX_RELOC_26_PCREL",/* name */
 
192
       true,                  /* partial_inplace */
 
193
       0xffff,                /* src_mask */
 
194
       0xffff,                /* dst_mask */
 
195
       true);                 /* pcrel_offset */
 
196
 
 
197
/* High 16 bits of symbol value.  */
 
198
static reloc_howto_type elf_dlx_reloc_16_hi =
 
199
HOWTO (R_DLX_RELOC_16_HI,     /* type */
 
200
       16,                    /* rightshift */
 
201
       2,                     /* size (0 = byte, 1 = short, 2 = long) */
 
202
       32,                    /* bitsize */
 
203
       false,                 /* pc_relative */
 
204
       0,                     /* bitpos */
 
205
       complain_overflow_dont, /* complain_on_overflow */
 
206
       _bfd_dlx_elf_hi16_reloc,/* special_function */
 
207
       "R_DLX_RELOC_16_HI",   /* name */
 
208
       true,                  /* partial_inplace */
 
209
       0xFFFF,                /* src_mask */
 
210
       0xffff,                /* dst_mask */
 
211
       false);                /* pcrel_offset */
 
212
 
 
213
  /* Low 16 bits of symbol value.  */
 
214
static reloc_howto_type elf_dlx_reloc_16_lo =
 
215
HOWTO (R_DLX_RELOC_16_LO,     /* type */
 
216
       0,                     /* rightshift */
 
217
       1,                     /* size (0 = byte, 1 = short, 2 = long) */
 
218
       16,                    /* bitsize */
 
219
       false,                 /* pc_relative */
 
220
       0,                     /* bitpos */
 
221
       complain_overflow_dont,/* complain_on_overflow */
 
222
       bfd_elf_generic_reloc, /* special_function */
 
223
       "R_DLX_RELOC_16_LO",   /* name */
 
224
       true,                  /* partial_inplace */
 
225
       0xffff,                /* src_mask */
 
226
       0xffff,                /* dst_mask */
 
227
       false);                /* pcrel_offset */
 
228
 
 
229
 
 
230
/* The gas default beheaver is not to preform the %hi modifier so that the
 
231
   GNU assembler can have the lower 16 bits offset placed in the insn, BUT
 
232
   we do like the gas to indicate it is %hi reloc type so when we in the link
 
233
   loader phase we can have the corrected hi16 vale replace the buggous lo16
 
234
   value that was placed there by gas.  */
 
235
 
 
236
static int skip_dlx_elf_hi16_reloc = 0;
 
237
 
 
238
int
 
239
set_dlx_skip_hi16_flag (flag)
 
240
     int flag;
 
241
{
 
242
  skip_dlx_elf_hi16_reloc = flag;
 
243
  return flag;
 
244
}
 
245
 
 
246
static bfd_reloc_status_type
 
247
_bfd_dlx_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
 
248
                         input_section, output_bfd, error_message)
 
249
     bfd *abfd;
 
250
     arelent *reloc_entry;
 
251
     asymbol *symbol;
 
252
     PTR data;
 
253
     asection *input_section;
 
254
     bfd *output_bfd;
 
255
     char **error_message;
 
256
{
 
257
  bfd_reloc_status_type ret;
 
258
  bfd_vma relocation;
 
259
 
 
260
  /* If the skip flag is set then we simply do the generic relocating, this
 
261
     is more of a hack for dlx gas/gld, so we do not need to do the %hi/%lo
 
262
     fixup like mips gld did.   */
 
263
#if 0
 
264
  printf ("DEBUG: skip_dlx_elf_hi16_reloc = 0x%08x\n", skip_dlx_elf_hi16_reloc);
 
265
#endif
 
266
  if (skip_dlx_elf_hi16_reloc)
 
267
    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
 
268
                          input_section, output_bfd, error_message);
 
269
 
 
270
  /* If we're relocating, and this an external symbol, we don't want
 
271
     to change anything.  */
 
272
  if (output_bfd != (bfd *) NULL
 
273
      && (symbol->flags & BSF_SECTION_SYM) == 0
 
274
      && reloc_entry->addend == 0)
 
275
    {
 
276
      reloc_entry->address += input_section->output_offset;
 
277
      return bfd_reloc_ok;
 
278
    }
 
279
 
 
280
  ret = bfd_reloc_ok;
 
281
 
 
282
  if (bfd_is_und_section (symbol->section)
 
283
      && output_bfd == (bfd *) NULL)
 
284
    ret = bfd_reloc_undefined;
 
285
 
 
286
#if 0
 
287
  {
 
288
    unsigned long vallo, val;
 
289
 
 
290
    vallo = bfd_get_16 (abfd, (bfd_byte *) data + reloc_entry->address);
 
291
    printf ("DEBUG: The relocation address = 0x%08x\n", reloc_entry->address);
 
292
    printf ("DEBUG: The symbol        = 0x%08x\n", vallo);
 
293
    printf ("DEBUG: The symbol name   = %s\n", bfd_asymbol_name (symbol));
 
294
    printf ("DEBUG: The symbol->value = 0x%08x\n", symbol->value);
 
295
    printf ("DEBUG: The vma           = 0x%08x\n", symbol->section->output_section->vma);
 
296
    printf ("DEBUG: The output_offset = 0x%08x\n", symbol->section->output_offset);
 
297
    printf ("DEBUG: The input_offset  = 0x%08x\n", input_section->output_offset);
 
298
    printf ("DEBUG: The input_vma     = 0x%08x\n", input_section->vma);
 
299
    printf ("DEBUG: The addend        = 0x%08x\n", reloc_entry->addend);
 
300
  }
 
301
#endif
 
302
 
 
303
  relocation = (bfd_is_com_section (symbol->section)) ? 0 : symbol->value;
 
304
  relocation += symbol->section->output_section->vma;
 
305
  relocation += symbol->section->output_offset;
 
306
  relocation += reloc_entry->addend;
 
307
  relocation += bfd_get_16 (abfd, (bfd_byte *)data + reloc_entry->address);
 
308
 
 
309
  if (reloc_entry->address > input_section->_cooked_size)
 
310
    return bfd_reloc_outofrange;
 
311
 
 
312
#if 0
 
313
  printf ("DEBUG: The finial relocation value = 0x%08x\n", relocation);
 
314
#endif
 
315
 
 
316
  bfd_put_16 (abfd, (short)((relocation >> 16) & 0xFFFF),
 
317
              (bfd_byte *)data + reloc_entry->address);
 
318
 
 
319
  return ret;
 
320
}
 
321
 
 
322
/* ELF relocs are against symbols.  If we are producing relocateable
 
323
   output, and the reloc is against an external symbol, and nothing
 
324
   has given us any additional addend, the resulting reloc will also
 
325
   be against the same symbol.  In such a case, we don't want to
 
326
   change anything about the way the reloc is handled, since it will
 
327
   all be done at final link time.  Rather than put special case code
 
328
   into bfd_perform_relocation, all the reloc types use this howto
 
329
   function.  It just short circuits the reloc if producing
 
330
   relocateable output against an external symbol.  */
 
331
 
 
332
static bfd_reloc_status_type
 
333
elf32_dlx_relocate16  (abfd, reloc_entry, symbol, data,
 
334
                       input_section, output_bfd, error_message)
 
335
     bfd *abfd;
 
336
     arelent *reloc_entry;
 
337
     asymbol *symbol;
 
338
     PTR data;
 
339
     asection *input_section;
 
340
     bfd *output_bfd;
 
341
     char **error_message ATTRIBUTE_UNUSED;
 
342
{
 
343
  unsigned long insn, vallo, allignment;
 
344
  int           val;
 
345
 
 
346
  /* HACK: I think this first condition is necessary when producing
 
347
     relocatable output.  After the end of HACK, the code is identical
 
348
     to bfd_elf_generic_reloc().  I would _guess_ the first change
 
349
     belongs there rather than here.  martindo 1998-10-23.  */
 
350
 
 
351
  if (skip_dlx_elf_hi16_reloc)
 
352
    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
 
353
                                 input_section, output_bfd, error_message);
 
354
 
 
355
  /* Check undefined section and undefined symbols  */
 
356
  if (bfd_is_und_section (symbol->section)
 
357
      && output_bfd == (bfd *) NULL)
 
358
    return bfd_reloc_undefined;
 
359
 
 
360
  /* Can not support a long jump to sections other then .text   */
 
361
  if (strcmp (input_section->name, symbol->section->output_section->name) != 0)
 
362
    {
 
363
      fprintf (stderr,
 
364
               "BFD Link Error: branch (PC rel16) to section (%s) not supported\n",
 
365
               symbol->section->output_section->name);
 
366
      return bfd_reloc_undefined;
 
367
    }
 
368
 
 
369
  insn  = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address);
 
370
  allignment = 1 << (input_section->output_section->alignment_power - 1);
 
371
  vallo = insn & 0x0000FFFF;
 
372
 
 
373
  if (vallo & 0x8000)
 
374
    vallo = ~(vallo | 0xFFFF0000) + 1;
 
375
 
 
376
  /* vallo points to the vma of next instruction.  */
 
377
  vallo += (((unsigned long)(input_section->output_section->vma +
 
378
                           input_section->output_offset) +
 
379
            allignment) & ~allignment);
 
380
 
 
381
  /* val is the displacement (PC relative to next instruction).  */
 
382
  val =  (symbol->section->output_offset +
 
383
          symbol->section->output_section->vma +
 
384
          symbol->value) - vallo;
 
385
#if 0
 
386
  printf ("DEBUG elf32_dlx_relocate: We are here\n");
 
387
  printf ("DEBUG: The insn            = 0x%08x\n", insn);
 
388
  printf ("DEBUG: The vallo           = 0x%08x\n", vallo);
 
389
  printf ("DEBUG: The val             = 0x%08x\n", val);
 
390
  printf ("DEBUG: The symbol name     = %s\n", bfd_asymbol_name (symbol));
 
391
  printf ("DEBUG: The symbol->value   = 0x%08x\n", symbol->value);
 
392
  printf ("DEBUG: The vma             = 0x%08x\n", symbol->section->output_section->vma);
 
393
  printf ("DEBUG: The lma             = 0x%08x\n", symbol->section->output_section->lma);
 
394
  printf ("DEBUG: The alignment_power = 0x%08x\n", symbol->section->output_section->alignment_power);
 
395
  printf ("DEBUG: The output_offset   = 0x%08x\n", symbol->section->output_offset);
 
396
  printf ("DEBUG: The addend          = 0x%08x\n", reloc_entry->addend);
 
397
#endif
 
398
 
 
399
  if (abs ((int) val) > 0x00007FFF)
 
400
    return bfd_reloc_outofrange;
 
401
 
 
402
  insn  = (insn & 0xFFFF0000) | (val & 0x0000FFFF);
 
403
 
 
404
  bfd_put_32 (abfd, insn,
 
405
              (bfd_byte *) data + reloc_entry->address);
 
406
 
 
407
  return bfd_reloc_ok;
 
408
}
 
409
 
 
410
static bfd_reloc_status_type
 
411
elf32_dlx_relocate26  (abfd, reloc_entry, symbol, data,
 
412
                       input_section, output_bfd, error_message)
 
413
     bfd *abfd;
 
414
     arelent *reloc_entry;
 
415
     asymbol *symbol;
 
416
     PTR data;
 
417
     asection *input_section;
 
418
     bfd *output_bfd;
 
419
     char **error_message ATTRIBUTE_UNUSED;
 
420
{
 
421
  unsigned long insn, vallo, allignment;
 
422
  int           val;
 
423
 
 
424
  /* HACK: I think this first condition is necessary when producing
 
425
     relocatable output.  After the end of HACK, the code is identical
 
426
     to bfd_elf_generic_reloc().  I would _guess_ the first change
 
427
     belongs there rather than here.  martindo 1998-10-23.  */
 
428
 
 
429
  if (skip_dlx_elf_hi16_reloc)
 
430
    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
 
431
                                 input_section, output_bfd, error_message);
 
432
 
 
433
  /* Check undefined section and undefined symbols.  */
 
434
  if (bfd_is_und_section (symbol->section)
 
435
      && output_bfd == (bfd *) NULL)
 
436
    return bfd_reloc_undefined;
 
437
 
 
438
  /* Can not support a long jump to sections other then .text   */
 
439
  if (strcmp (input_section->name, symbol->section->output_section->name) != 0)
 
440
    {
 
441
      fprintf (stderr,
 
442
               "BFD Link Error: jump (PC rel26) to section (%s) not supported\n",
 
443
               symbol->section->output_section->name);
 
444
      return bfd_reloc_undefined;
 
445
    }
 
446
 
 
447
  insn  = bfd_get_32 (abfd, (bfd_byte *)data + reloc_entry->address);
 
448
  allignment = 1 << (input_section->output_section->alignment_power - 1);
 
449
  vallo = insn & 0x03FFFFFF;
 
450
 
 
451
  if (vallo & 0x03000000)
 
452
    vallo = ~(vallo | 0xFC000000) + 1;
 
453
 
 
454
  /* vallo is the vma for the next instruction.  */
 
455
  vallo += (((unsigned long) (input_section->output_section->vma +
 
456
                              input_section->output_offset) +
 
457
             allignment) & ~allignment);
 
458
 
 
459
  /* val is the displacement (PC relative to next instruction).  */
 
460
  val = (symbol->section->output_offset +
 
461
         symbol->section->output_section->vma + symbol->value)
 
462
    - vallo;
 
463
#if 0
 
464
  printf ("DEBUG elf32_dlx_relocate26: We are here\n");
 
465
  printf ("DEBUG: The insn          = 0x%08x\n", insn);
 
466
  printf ("DEBUG: The vallo         = 0x%08x\n", vallo);
 
467
  printf ("DEBUG: The val           = 0x%08x\n", val);
 
468
  printf ("DEBUG: The abs(val)      = 0x%08x\n", abs (val));
 
469
  printf ("DEBUG: The symbol name   = %s\n", bfd_asymbol_name (symbol));
 
470
  printf ("DEBUG: The symbol->value = 0x%08x\n", symbol->value);
 
471
  printf ("DEBUG: The vma           = 0x%08x\n", symbol->section->output_section->vma);
 
472
  printf ("DEBUG: The output_offset = 0x%08x\n", symbol->section->output_offset);
 
473
  printf ("DEBUG: The input_vma     = 0x%08x\n", input_section->output_section->vma);
 
474
  printf ("DEBUG: The input_offset  = 0x%08x\n", input_section->output_offset);
 
475
  printf ("DEBUG: The input_name    = %s\n", input_section->name);
 
476
  printf ("DEBUG: The addend        = 0x%08x\n", reloc_entry->addend);
 
477
#endif
 
478
 
 
479
  if (abs ((int) val) > 0x01FFFFFF)
 
480
    return bfd_reloc_outofrange;
 
481
 
 
482
  insn  = (insn & 0xFC000000) | (val & 0x03FFFFFF);
 
483
  bfd_put_32 (abfd, insn,
 
484
              (bfd_byte *) data + reloc_entry->address);
 
485
 
 
486
  return bfd_reloc_ok;
 
487
}
 
488
 
 
489
/* A mapping from BFD reloc types to DLX ELF reloc types.
 
490
   Stolen from elf32-mips.c.
 
491
 
 
492
   More about this table - for dlx elf relocation we do not really
 
493
   need this table, if we have a rtype defined in this table will
 
494
   caused tc_gen_relocate confused and die on us, but if we remove
 
495
   this table it will caused more problem, so for now simple soulation
 
496
   is to remove those entries which may cause problem.  */
 
497
struct elf_reloc_map
 
498
{
 
499
  bfd_reloc_code_real_type bfd_reloc_val;
 
500
  enum elf_dlx_reloc_type elf_reloc_val;
 
501
};
 
502
 
 
503
static const struct elf_reloc_map dlx_reloc_map[] =
 
504
  {
 
505
    { BFD_RELOC_NONE,           R_DLX_NONE },
 
506
    { BFD_RELOC_16,             R_DLX_RELOC_16 },
 
507
#if 0
 
508
    { BFD_RELOC_DLX_JMP26,      R_DLX_RELOC_26_PCREL },
 
509
#endif
 
510
    { BFD_RELOC_32,             R_DLX_RELOC_32 },
 
511
    { BFD_RELOC_DLX_HI16_S,     R_DLX_RELOC_16_HI },
 
512
    { BFD_RELOC_DLX_LO16,       R_DLX_RELOC_16_LO },
 
513
    { BFD_RELOC_VTABLE_INHERIT, R_DLX_GNU_VTINHERIT },
 
514
    { BFD_RELOC_VTABLE_ENTRY,   R_DLX_GNU_VTENTRY }
 
515
  };
 
516
 
 
517
 
 
518
/* Look through the relocs for a section during the first phase.
 
519
   Since we don't do .gots or .plts, we just need to consider the
 
520
   virtual table relocs for gc.  */
 
521
 
 
522
static boolean
 
523
elf32_dlx_check_relocs (abfd, info, sec, relocs)
 
524
     bfd *abfd;
 
525
     struct bfd_link_info *info;
 
526
     asection *sec;
 
527
     const Elf_Internal_Rela *relocs;
 
528
{
 
529
  Elf_Internal_Shdr *symtab_hdr;
 
530
  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
 
531
  const Elf_Internal_Rela *rel;
 
532
  const Elf_Internal_Rela *rel_end;
 
533
 
 
534
  if (info->relocateable)
 
535
    return true;
 
536
 
 
537
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
 
538
  sym_hashes = elf_sym_hashes (abfd);
 
539
  sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
 
540
  if (!elf_bad_symtab (abfd))
 
541
    sym_hashes_end -= symtab_hdr->sh_info;
 
542
 
 
543
  rel_end = relocs + sec->reloc_count;
 
544
  for (rel = relocs; rel < rel_end; rel++)
 
545
    {
 
546
      struct elf_link_hash_entry *h;
 
547
      unsigned long r_symndx;
 
548
 
 
549
      r_symndx = ELF32_R_SYM (rel->r_info);
 
550
      if (r_symndx < symtab_hdr->sh_info)
 
551
        h = NULL;
 
552
      else
 
553
        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 
554
 
 
555
      switch (ELF32_R_TYPE (rel->r_info))
 
556
        {
 
557
        /* This relocation describes the C++ object vtable hierarchy.
 
558
           Reconstruct it for later use during GC.  */
 
559
        case R_DLX_GNU_VTINHERIT:
 
560
          if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
 
561
            return false;
 
562
          break;
 
563
 
 
564
        /* This relocation describes which C++ vtable entries are actually
 
565
           used.  Record for later use during GC.  */
 
566
        case R_DLX_GNU_VTENTRY:
 
567
          if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
 
568
            return false;
 
569
          break;
 
570
        }
 
571
    }
 
572
 
 
573
  return true;
 
574
}
 
575
 
 
576
/* Given a BFD reloc type, return a howto structure.  */
 
577
 
 
578
static reloc_howto_type *
 
579
elf32_dlx_reloc_type_lookup (abfd, code)
 
580
     bfd *abfd ATTRIBUTE_UNUSED;
 
581
     bfd_reloc_code_real_type code;
 
582
{
 
583
  unsigned int i;
 
584
 
 
585
  for (i = 0; i < sizeof (dlx_reloc_map) / sizeof (struct elf_reloc_map); i++)
 
586
    if (dlx_reloc_map[i].bfd_reloc_val == code)
 
587
      return &dlx_elf_howto_table[(int) dlx_reloc_map[i].elf_reloc_val];
 
588
 
 
589
  switch (code)
 
590
    {
 
591
    default:
 
592
      bfd_set_error (bfd_error_bad_value);
 
593
      return NULL;
 
594
    case BFD_RELOC_16_PCREL_S2:
 
595
      return &elf_dlx_gnu_rel16_s2;
 
596
    case BFD_RELOC_DLX_JMP26:
 
597
      return &elf_dlx_gnu_rel26_s2;
 
598
    case BFD_RELOC_HI16_S:
 
599
      return &elf_dlx_reloc_16_hi;
 
600
    case BFD_RELOC_LO16:
 
601
      return &elf_dlx_reloc_16_lo;
 
602
    }
 
603
}
 
604
 
 
605
static reloc_howto_type *
 
606
dlx_rtype_to_howto (r_type)
 
607
     unsigned int r_type;
 
608
{
 
609
  switch (r_type)
 
610
    {
 
611
    case R_DLX_RELOC_16_PCREL:
 
612
      return & elf_dlx_gnu_rel16_s2;
 
613
      break;
 
614
    case R_DLX_RELOC_26_PCREL:
 
615
      return & elf_dlx_gnu_rel26_s2;
 
616
      break;
 
617
    case R_DLX_RELOC_16_HI:
 
618
      return & elf_dlx_reloc_16_hi;
 
619
      break;
 
620
    case R_DLX_RELOC_16_LO:
 
621
      return & elf_dlx_reloc_16_lo;
 
622
      break;
 
623
 
 
624
    default:
 
625
      BFD_ASSERT (r_type < (unsigned int) R_DLX_max);
 
626
      return & dlx_elf_howto_table[r_type];
 
627
      break;
 
628
    }
 
629
}
 
630
 
 
631
static void
 
632
elf32_dlx_info_to_howto (abfd, cache_ptr, dst)
 
633
     bfd * abfd ATTRIBUTE_UNUSED;
 
634
     arelent * cache_ptr ATTRIBUTE_UNUSED;
 
635
     Elf32_Internal_Rela * dst ATTRIBUTE_UNUSED;
 
636
{
 
637
  abort ();
 
638
}
 
639
 
 
640
static void
 
641
elf32_dlx_info_to_howto_rel (abfd, cache_ptr, dst)
 
642
     bfd *abfd ATTRIBUTE_UNUSED;
 
643
     arelent *cache_ptr;
 
644
     Elf32_Internal_Rel *dst;
 
645
{
 
646
  unsigned int r_type;
 
647
 
 
648
  r_type = ELF32_R_TYPE (dst->r_info);
 
649
  cache_ptr->howto = dlx_rtype_to_howto (r_type);
 
650
  return;
 
651
}
 
652
 
 
653
#define TARGET_BIG_SYM          bfd_elf32_dlx_big_vec
 
654
#define TARGET_BIG_NAME         "elf32-dlx"
 
655
#define ELF_ARCH                bfd_arch_dlx
 
656
#define ELF_MACHINE_CODE        EM_DLX
 
657
#define ELF_MAXPAGESIZE         1 /* FIXME: This number is wrong,  It should be the page size in bytes.  */
 
658
 
 
659
#include "elf32-target.h"