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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* 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"

powered by: WebSVN 2.1.0

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