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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [bfd/] [elf32-ip2k.c] - Blame information for rev 472

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

Line No. Rev Author Line
1 330 jeremybenn
/* Ubicom IP2xxx specific support for 32-bit ELF
2
   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of BFD, the Binary File Descriptor library.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include "sysdep.h"
23
#include "bfd.h"
24
#include "libbfd.h"
25
#include "elf-bfd.h"
26
#include "elf/ip2k.h"
27
 
28
/* Struct used to pass miscellaneous paramaters which
29
   helps to avoid overly long parameter lists.  */
30
struct misc
31
{
32
  Elf_Internal_Shdr *  symtab_hdr;
33
  Elf_Internal_Rela *  irelbase;
34
  bfd_byte *           contents;
35
  Elf_Internal_Sym *   isymbuf;
36
};
37
 
38
struct ip2k_opcode
39
{
40
  unsigned short opcode;
41
  unsigned short mask;
42
};
43
 
44
static bfd_boolean ip2k_relaxed = FALSE;
45
 
46
static const struct ip2k_opcode ip2k_page_opcode[] =
47
{
48
  {0x0010, 0xFFF8},     /* Page.  */
49
  {0x0000, 0x0000},
50
};
51
 
52
#define IS_PAGE_OPCODE(code) \
53
  ip2k_is_opcode (code, ip2k_page_opcode)
54
 
55
static const struct ip2k_opcode ip2k_jmp_opcode[] =
56
{
57
  {0xE000, 0xE000},     /* Jmp.  */
58
  {0x0000, 0x0000},
59
};
60
 
61
#define IS_JMP_OPCODE(code) \
62
  ip2k_is_opcode (code, ip2k_jmp_opcode)
63
 
64
static const struct ip2k_opcode ip2k_snc_opcode[] =
65
{
66
  {0xA00B, 0xFFFF},     /* Snc.  */
67
  {0x0000, 0x0000},
68
};
69
 
70
#define IS_SNC_OPCODE(code) \
71
  ip2k_is_opcode (code, ip2k_snc_opcode)
72
 
73
static const struct ip2k_opcode ip2k_inc_1sp_opcode[] =
74
{
75
  {0x2B81, 0xFFFF},     /* Inc 1(SP).  */
76
  {0x0000, 0x0000},
77
};
78
 
79
#define IS_INC_1SP_OPCODE(code) \
80
  ip2k_is_opcode (code, ip2k_inc_1sp_opcode)
81
 
82
static const struct ip2k_opcode ip2k_add_2sp_w_opcode[] =
83
{
84
  {0x1F82, 0xFFFF},     /* Add 2(SP),w.  */
85
  {0x0000, 0x0000},
86
};
87
 
88
#define IS_ADD_2SP_W_OPCODE(code) \
89
  ip2k_is_opcode (code, ip2k_add_2sp_w_opcode)
90
 
91
static const struct ip2k_opcode ip2k_add_w_wreg_opcode[] =
92
{
93
  {0x1C0A, 0xFFFF},     /* Add w,wreg.  */
94
  {0x1E0A, 0xFFFF},     /* Add wreg,w.  */
95
  {0x0000, 0x0000},
96
};
97
 
98
#define IS_ADD_W_WREG_OPCODE(code) \
99
  ip2k_is_opcode (code, ip2k_add_w_wreg_opcode)
100
 
101
static const struct ip2k_opcode ip2k_add_pcl_w_opcode[] =
102
{
103
  {0x1E09, 0xFFFF},     /* Add pcl,w.  */
104
  {0x0000, 0x0000},
105
};
106
 
107
#define IS_ADD_PCL_W_OPCODE(code) \
108
  ip2k_is_opcode (code, ip2k_add_pcl_w_opcode)
109
 
110
static const struct ip2k_opcode ip2k_skip_opcodes[] =
111
{
112
  {0xB000, 0xF000},     /* sb */
113
  {0xA000, 0xF000},     /* snb */
114
  {0x7600, 0xFE00},     /* cse/csne #lit */
115
  {0x5800, 0xFC00},     /* incsnz */
116
  {0x4C00, 0xFC00},     /* decsnz */
117
  {0x4000, 0xFC00},     /* cse/csne */
118
  {0x3C00, 0xFC00},     /* incsz */
119
  {0x2C00, 0xFC00},     /* decsz */
120
  {0x0000, 0x0000},
121
};
122
 
123
#define IS_SKIP_OPCODE(code) \
124
  ip2k_is_opcode (code, ip2k_skip_opcodes)
125
 
126
/* Relocation tables.  */
127
static reloc_howto_type ip2k_elf_howto_table [] =
128
{
129
#define IP2K_HOWTO(t,rs,s,bs,pr,bp,name,sm,dm) \
130
    HOWTO(t,                    /* type */ \
131
          rs,                   /* rightshift */ \
132
          s,                    /* size (0 = byte, 1 = short, 2 = long) */ \
133
          bs,                   /* bitsize */ \
134
          pr,                   /* pc_relative */ \
135
          bp,                   /* bitpos */ \
136
          complain_overflow_dont,/* complain_on_overflow */ \
137
          bfd_elf_generic_reloc,/* special_function */ \
138
          name,                 /* name */ \
139
          FALSE,                /* partial_inplace */ \
140
          sm,                   /* src_mask */ \
141
          dm,                   /* dst_mask */ \
142
          pr)                   /* pcrel_offset */
143
 
144
  /* This reloc does nothing.  */
145
  IP2K_HOWTO (R_IP2K_NONE, 0,2,32, FALSE, 0, "R_IP2K_NONE", 0, 0),
146
  /* A 16 bit absolute relocation.  */
147
  IP2K_HOWTO (R_IP2K_16, 0,1,16, FALSE, 0, "R_IP2K_16", 0, 0xffff),
148
  /* A 32 bit absolute relocation.  */
149
  IP2K_HOWTO (R_IP2K_32, 0,2,32, FALSE, 0, "R_IP2K_32", 0, 0xffffffff),
150
  /* A 8-bit data relocation for the FR9 field.  Ninth bit is computed specially.  */
151
  IP2K_HOWTO (R_IP2K_FR9, 0,1,9, FALSE, 0, "R_IP2K_FR9", 0, 0x00ff),
152
  /* A 4-bit data relocation.  */
153
  IP2K_HOWTO (R_IP2K_BANK, 8,1,4, FALSE, 0, "R_IP2K_BANK", 0, 0x000f),
154
  /* A 13-bit insn relocation - word address => right-shift 1 bit extra.  */
155
  IP2K_HOWTO (R_IP2K_ADDR16CJP, 1,1,13, FALSE, 0, "R_IP2K_ADDR16CJP", 0, 0x1fff),
156
  /* A 3-bit insn relocation - word address => right-shift 1 bit extra.  */
157
  IP2K_HOWTO (R_IP2K_PAGE3, 14,1,3, FALSE, 0, "R_IP2K_PAGE3", 0, 0x0007),
158
  /* Two 8-bit data relocations.  */
159
  IP2K_HOWTO (R_IP2K_LO8DATA, 0,1,8, FALSE, 0, "R_IP2K_LO8DATA", 0, 0x00ff),
160
  IP2K_HOWTO (R_IP2K_HI8DATA, 8,1,8, FALSE, 0, "R_IP2K_HI8DATA", 0, 0x00ff),
161
  /* Two 8-bit insn relocations.  word address => right-shift 1 bit extra.  */
162
  IP2K_HOWTO (R_IP2K_LO8INSN, 1,1,8, FALSE, 0, "R_IP2K_LO8INSN", 0, 0x00ff),
163
  IP2K_HOWTO (R_IP2K_HI8INSN, 9,1,8, FALSE, 0, "R_IP2K_HI8INSN", 0, 0x00ff),
164
 
165
  /* Special 1 bit relocation for SKIP instructions.  */
166
  IP2K_HOWTO (R_IP2K_PC_SKIP, 1,1,1, FALSE, 12, "R_IP2K_PC_SKIP", 0xfffe, 0x1000),
167
  /* 16 bit word address.  */
168
  IP2K_HOWTO (R_IP2K_TEXT, 1,1,16, FALSE, 0, "R_IP2K_TEXT", 0, 0xffff),
169
  /* A 7-bit offset relocation for the FR9 field.  Eigth and ninth bit comes from insn.  */
170
  IP2K_HOWTO (R_IP2K_FR_OFFSET, 0,1,9, FALSE, 0, "R_IP2K_FR_OFFSET", 0x180, 0x007f),
171
  /* Bits 23:16 of an address.  */
172
  IP2K_HOWTO (R_IP2K_EX8DATA, 16,1,8, FALSE, 0, "R_IP2K_EX8DATA", 0, 0x00ff),
173
};
174
 
175
 
176
/* Map BFD reloc types to IP2K ELF reloc types.  */
177
 
178
static reloc_howto_type *
179
ip2k_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
180
                        bfd_reloc_code_real_type code)
181
{
182
  /* Note that the ip2k_elf_howto_table is indxed by the R_
183
     constants.  Thus, the order that the howto records appear in the
184
     table *must* match the order of the relocation types defined in
185
     include/elf/ip2k.h.  */
186
 
187
  switch (code)
188
    {
189
    case BFD_RELOC_NONE:
190
      return &ip2k_elf_howto_table[ (int) R_IP2K_NONE];
191
    case BFD_RELOC_16:
192
      return &ip2k_elf_howto_table[ (int) R_IP2K_16];
193
    case BFD_RELOC_32:
194
      return &ip2k_elf_howto_table[ (int) R_IP2K_32];
195
    case BFD_RELOC_IP2K_FR9:
196
      return &ip2k_elf_howto_table[ (int) R_IP2K_FR9];
197
    case BFD_RELOC_IP2K_BANK:
198
      return &ip2k_elf_howto_table[ (int) R_IP2K_BANK];
199
    case BFD_RELOC_IP2K_ADDR16CJP:
200
      return &ip2k_elf_howto_table[ (int) R_IP2K_ADDR16CJP];
201
    case BFD_RELOC_IP2K_PAGE3:
202
      return &ip2k_elf_howto_table[ (int) R_IP2K_PAGE3];
203
    case BFD_RELOC_IP2K_LO8DATA:
204
      return &ip2k_elf_howto_table[ (int) R_IP2K_LO8DATA];
205
    case BFD_RELOC_IP2K_HI8DATA:
206
      return &ip2k_elf_howto_table[ (int) R_IP2K_HI8DATA];
207
    case BFD_RELOC_IP2K_LO8INSN:
208
      return &ip2k_elf_howto_table[ (int) R_IP2K_LO8INSN];
209
    case BFD_RELOC_IP2K_HI8INSN:
210
      return &ip2k_elf_howto_table[ (int) R_IP2K_HI8INSN];
211
    case BFD_RELOC_IP2K_PC_SKIP:
212
      return &ip2k_elf_howto_table[ (int) R_IP2K_PC_SKIP];
213
    case BFD_RELOC_IP2K_TEXT:
214
      return &ip2k_elf_howto_table[ (int) R_IP2K_TEXT];
215
    case BFD_RELOC_IP2K_FR_OFFSET:
216
      return &ip2k_elf_howto_table[ (int) R_IP2K_FR_OFFSET];
217
    case BFD_RELOC_IP2K_EX8DATA:
218
      return &ip2k_elf_howto_table[ (int) R_IP2K_EX8DATA];
219
    default:
220
      /* Pacify gcc -Wall.  */
221
      return NULL;
222
    }
223
  return NULL;
224
}
225
 
226
static reloc_howto_type *
227
ip2k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
228
{
229
  unsigned int i;
230
 
231
  for (i = 0;
232
       i < sizeof (ip2k_elf_howto_table) / sizeof (ip2k_elf_howto_table[0]);
233
       i++)
234
    if (ip2k_elf_howto_table[i].name != NULL
235
        && strcasecmp (ip2k_elf_howto_table[i].name, r_name) == 0)
236
      return &ip2k_elf_howto_table[i];
237
 
238
  return NULL;
239
}
240
 
241
static void
242
ip2k_get_mem (bfd *abfd ATTRIBUTE_UNUSED,
243
              bfd_byte *addr,
244
              int length,
245
              bfd_byte *ptr)
246
{
247
  while (length --)
248
    * ptr ++ = bfd_get_8 (abfd, addr ++);
249
}
250
 
251
static bfd_boolean
252
ip2k_is_opcode (bfd_byte *code, const struct ip2k_opcode *opcodes)
253
{
254
  unsigned short insn = (code[0] << 8) | code[1];
255
 
256
  while (opcodes->mask != 0)
257
    {
258
      if ((insn & opcodes->mask) == opcodes->opcode)
259
        return TRUE;
260
 
261
      opcodes ++;
262
    }
263
 
264
  return FALSE;
265
}
266
 
267
#define PAGENO(ABSADDR) ((ABSADDR) & 0xFFFFC000)
268
#define BASEADDR(SEC)   ((SEC)->output_section->vma + (SEC)->output_offset)
269
 
270
#define UNDEFINED_SYMBOL (~(bfd_vma)0)
271
 
272
/* Return the value of the symbol associated with the relocation IREL.  */
273
 
274
static bfd_vma
275
symbol_value (bfd *abfd,
276
              Elf_Internal_Shdr *symtab_hdr,
277
              Elf_Internal_Sym *isymbuf,
278
              Elf_Internal_Rela *irel)
279
{
280
  if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
281
    {
282
      Elf_Internal_Sym *isym;
283
      asection *sym_sec;
284
 
285
      isym = isymbuf + ELF32_R_SYM (irel->r_info);
286
      if (isym->st_shndx == SHN_UNDEF)
287
        sym_sec = bfd_und_section_ptr;
288
      else if (isym->st_shndx == SHN_ABS)
289
        sym_sec = bfd_abs_section_ptr;
290
      else if (isym->st_shndx == SHN_COMMON)
291
        sym_sec = bfd_com_section_ptr;
292
      else
293
        sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
294
 
295
      return isym->st_value + BASEADDR (sym_sec);
296
    }
297
  else
298
    {
299
      unsigned long indx;
300
      struct elf_link_hash_entry *h;
301
 
302
      indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
303
      h = elf_sym_hashes (abfd)[indx];
304
      BFD_ASSERT (h != NULL);
305
 
306
      if (h->root.type != bfd_link_hash_defined
307
          && h->root.type != bfd_link_hash_defweak)
308
        return UNDEFINED_SYMBOL;
309
 
310
      return (h->root.u.def.value + BASEADDR (h->root.u.def.section));
311
    }
312
}
313
 
314
/* Determine if the instruction sequence matches that for
315
   the prologue of a switch dispatch table with fewer than
316
   128 entries.
317
 
318
          sc
319
          page    $nnn0
320
          jmp     $nnn0
321
          add     w,wreg
322
          add     pcl,w
323
  addr=>
324
          page    $nnn1
325
          jmp     $nnn1
326
           page    $nnn2
327
           jmp     $nnn2
328
           ...
329
           page    $nnnN
330
           jmp     $nnnN
331
 
332
  After relaxation.
333
           sc
334
           page    $nnn0
335
           jmp     $nnn0
336
           add     pcl,w
337
  addr=>
338
           jmp     $nnn1
339
           jmp     $nnn2
340
           ...
341
          jmp     $nnnN  */
342
 
343
static int
344
ip2k_is_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED,
345
                          asection *sec,
346
                          bfd_vma addr,
347
                          bfd_byte *contents)
348
{
349
  bfd_byte code[4];
350
  int table_index = 0;
351
 
352
  /* Check current page-jmp.  */
353
  if (addr + 4 > sec->size)
354
    return -1;
355
 
356
  ip2k_get_mem (abfd, contents + addr, 4, code);
357
 
358
  if ((! IS_PAGE_OPCODE (code + 0))
359
      || (! IS_JMP_OPCODE (code + 2)))
360
    return -1;
361
 
362
  /* Search back.  */
363
  while (1)
364
    {
365
      if (addr < 4)
366
        return -1;
367
 
368
      /* Check previous 2 instructions.  */
369
      ip2k_get_mem (abfd, contents + addr - 4, 4, code);
370
      if ((IS_ADD_W_WREG_OPCODE (code + 0))
371
          && (IS_ADD_PCL_W_OPCODE (code + 2)))
372
        return table_index;
373
 
374
      if ((! IS_PAGE_OPCODE (code + 0))
375
          || (! IS_JMP_OPCODE (code + 2)))
376
        return -1;
377
 
378
      table_index++;
379
      addr -= 4;
380
    }
381
}
382
 
383
/* Determine if the instruction sequence matches that for
384
   the prologue switch dispatch table with fewer than
385
   256 entries but more than 127.
386
 
387
   Before relaxation.
388
          push    %lo8insn(label) ; Push address of table
389
          push    %hi8insn(label)
390
          add     w,wreg          ; index*2 => offset
391
          snc                     ; CARRY SET?
392
          inc     1(sp)           ; Propagate MSB into table address
393
          add     2(sp),w         ; Add low bits of offset to table address
394
          snc                     ; and handle any carry-out
395
          inc     1(sp)
396
   addr=>
397
          page    __indjmp        ; Do an indirect jump to that location
398
          jmp     __indjmp
399
   label:                         ; case dispatch table starts here
400
           page    $nnn1
401
           jmp     $nnn1
402
           page    $nnn2
403
           jmp     $nnn2
404
           ...
405
           page    $nnnN
406
           jmp     $nnnN
407
 
408
  After relaxation.
409
          push    %lo8insn(label) ; Push address of table
410
          push    %hi8insn(label)
411
          add     2(sp),w         ; Add low bits of offset to table address
412
          snc                     ; and handle any carry-out
413
          inc     1(sp)
414
  addr=>
415
          page    __indjmp        ; Do an indirect jump to that location
416
          jmp     __indjmp
417
   label:                         ; case dispatch table starts here
418
          jmp     $nnn1
419
          jmp     $nnn2
420
          ...
421
          jmp     $nnnN  */
422
 
423
static int
424
ip2k_is_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED,
425
                          asection *sec,
426
                          bfd_vma addr,
427
                          bfd_byte *contents)
428
{
429
  bfd_byte code[16];
430
  int table_index = 0;
431
 
432
  /* Check current page-jmp.  */
433
  if (addr + 4 > sec->size)
434
    return -1;
435
 
436
  ip2k_get_mem (abfd, contents + addr, 4, code);
437
  if ((! IS_PAGE_OPCODE (code + 0))
438
      || (! IS_JMP_OPCODE (code + 2)))
439
    return -1;
440
 
441
  /* Search back.  */
442
  while (1)
443
    {
444
      if (addr < 16)
445
        return -1;
446
 
447
      /* Check previous 8 instructions.  */
448
      ip2k_get_mem (abfd, contents + addr - 16, 16, code);
449
      if ((IS_ADD_W_WREG_OPCODE (code + 0))
450
          && (IS_SNC_OPCODE (code + 2))
451
          && (IS_INC_1SP_OPCODE (code + 4))
452
          && (IS_ADD_2SP_W_OPCODE (code + 6))
453
          && (IS_SNC_OPCODE (code + 8))
454
          && (IS_INC_1SP_OPCODE (code + 10))
455
          && (IS_PAGE_OPCODE (code + 12))
456
          && (IS_JMP_OPCODE (code + 14)))
457
        return table_index;
458
 
459
      if ((IS_ADD_W_WREG_OPCODE (code + 2))
460
          && (IS_SNC_OPCODE (code + 4))
461
          && (IS_INC_1SP_OPCODE (code + 6))
462
          && (IS_ADD_2SP_W_OPCODE (code + 8))
463
          && (IS_SNC_OPCODE (code + 10))
464
          && (IS_INC_1SP_OPCODE (code + 12))
465
          && (IS_JMP_OPCODE (code + 14)))
466
        return table_index;
467
 
468
      if ((! IS_PAGE_OPCODE (code + 0))
469
          || (! IS_JMP_OPCODE (code + 2)))
470
        return -1;
471
 
472
      table_index++;
473
      addr -= 4;
474
    }
475
}
476
 
477
/* Returns the expected page state for the given instruction not including
478
   the effect of page instructions.  */
479
 
480
static bfd_vma
481
ip2k_nominal_page_bits (bfd *abfd ATTRIBUTE_UNUSED,
482
                        asection *sec,
483
                        bfd_vma addr,
484
                        bfd_byte *contents)
485
{
486
  bfd_vma page = PAGENO (BASEADDR (sec) + addr);
487
 
488
  /* Check if section flows into this page. If not then the page
489
     bits are assumed to match the PC. This will be true unless
490
     the user has a page instruction without a call/jump, in which
491
     case they are on their own.  */
492
  if (PAGENO (BASEADDR (sec)) == page)
493
    return page;
494
 
495
  /* Section flows across page boundary. The page bits should match
496
     the PC unless there is a possible flow from the previous page,
497
     in which case it is not possible to determine the value of the
498
     page bits.  */
499
  while (PAGENO (BASEADDR (sec) + addr - 2) == page)
500
    {
501
      bfd_byte code[2];
502
 
503
      addr -= 2;
504
      ip2k_get_mem (abfd, contents + addr, 2, code);
505
      if (!IS_PAGE_OPCODE (code))
506
        continue;
507
 
508
      /* Found a page instruction, check if jump table.  */
509
      if (ip2k_is_switch_table_128 (abfd, sec, addr, contents) != -1)
510
        /* Jump table => page is conditional.  */
511
        continue;
512
 
513
      if (ip2k_is_switch_table_256 (abfd, sec, addr, contents) != -1)
514
        /* Jump table => page is conditional.  */
515
        continue;
516
 
517
      /* Found a page instruction, check if conditional.  */
518
      if (addr >= 2)
519
        {
520
          ip2k_get_mem (abfd, contents + addr - 2, 2, code);
521
          if (IS_SKIP_OPCODE (code))
522
            /* Page is conditional.  */
523
            continue;
524
        }
525
 
526
      /* Unconditional page instruction => page bits should be correct.  */
527
      return page;
528
    }
529
 
530
  /* Flow from previous page => page bits are impossible to determine.  */
531
  return 0;
532
}
533
 
534
static bfd_boolean
535
ip2k_test_page_insn (bfd *abfd ATTRIBUTE_UNUSED,
536
                     asection *sec,
537
                     Elf_Internal_Rela *irel,
538
                     struct misc *misc)
539
{
540
  bfd_vma symval;
541
 
542
  /* Get the value of the symbol referred to by the reloc.  */
543
  symval = symbol_value (abfd, misc->symtab_hdr, misc->isymbuf, irel);
544
  if (symval == UNDEFINED_SYMBOL)
545
    /* This appears to be a reference to an undefined
546
       symbol.  Just ignore it--it will be caught by the
547
       regular reloc processing.  */
548
    return FALSE;
549
 
550
  /* Test if we can delete this page instruction.  */
551
  if (PAGENO (symval + irel->r_addend) !=
552
      ip2k_nominal_page_bits (abfd, sec, irel->r_offset, misc->contents))
553
    return FALSE;
554
 
555
  return TRUE;
556
}
557
 
558
/* Parts of a Stabs entry.  */
559
 
560
#define STRDXOFF   0
561
#define TYPEOFF    4
562
#define OTHEROFF   5
563
#define DESCOFF    6
564
#define VALOFF     8
565
#define STABSIZE   12
566
 
567
/* Adjust all the relocations entries after adding or inserting instructions.  */
568
 
569
static void
570
adjust_all_relocations (bfd *abfd,
571
                        asection *sec,
572
                        bfd_vma addr,
573
                        bfd_vma endaddr,
574
                        int count,
575
                        int noadj)
576
{
577
  Elf_Internal_Shdr *symtab_hdr;
578
  Elf_Internal_Sym *isymbuf, *isym, *isymend;
579
  unsigned int shndx;
580
  Elf_Internal_Rela *irel, *irelend, *irelbase;
581
  struct elf_link_hash_entry **sym_hashes;
582
  struct elf_link_hash_entry **end_hashes;
583
  unsigned int symcount;
584
  asection *stab;
585
 
586
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
587
  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
588
 
589
  shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
590
 
591
  irelbase = elf_section_data (sec)->relocs;
592
  irelend = irelbase + sec->reloc_count;
593
 
594
  for (irel = irelbase; irel < irelend; irel++)
595
    {
596
      if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
597
        {
598
          /* Get the value of the symbol referred to by the reloc.  */
599
          if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
600
            {
601
              asection *sym_sec;
602
 
603
              /* A local symbol.  */
604
              isym = isymbuf + ELF32_R_SYM (irel->r_info);
605
              sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
606
 
607
              if (isym->st_shndx == shndx)
608
                {
609
                  bfd_vma baseaddr = BASEADDR (sec);
610
                  bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
611
                                   + irel->r_addend;
612
 
613
                  if ((baseaddr + addr + noadj) <= symval
614
                      && symval < (baseaddr + endaddr))
615
                    irel->r_addend += count;
616
                }
617
            }
618
        }
619
 
620
      /* Do this only for PC space relocations.  */
621
      if (addr <= irel->r_offset && irel->r_offset < endaddr)
622
        irel->r_offset += count;
623
    }
624
 
625
  /* Now fix the stab relocations.  */
626
  stab = bfd_get_section_by_name (abfd, ".stab");
627
  if (stab)
628
    {
629
      bfd_byte *stabcontents, *stabend, *stabp;
630
      bfd_size_type stab_size = stab->rawsize ? stab->rawsize : stab->size;
631
 
632
      irelbase = elf_section_data (stab)->relocs;
633
      irelend = irelbase + stab->reloc_count;
634
 
635
      /* Pull out the contents of the stab section.  */
636
      if (elf_section_data (stab)->this_hdr.contents != NULL)
637
        stabcontents = elf_section_data (stab)->this_hdr.contents;
638
      else
639
        {
640
          if (!bfd_malloc_and_get_section (abfd, stab, &stabcontents))
641
            {
642
              if (stabcontents != NULL)
643
                free (stabcontents);
644
              return;
645
            }
646
 
647
          /* We need to remember this.  */
648
          elf_section_data (stab)->this_hdr.contents = stabcontents;
649
        }
650
 
651
      stabend = stabcontents + stab_size;
652
 
653
      for (irel = irelbase; irel < irelend; irel++)
654
        {
655
          if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
656
            {
657
              /* Get the value of the symbol referred to by the reloc.  */
658
              if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
659
                {
660
                  asection *sym_sec;
661
 
662
                  /* A local symbol.  */
663
                  isym = isymbuf + ELF32_R_SYM (irel->r_info);
664
                  sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
665
 
666
                  if (sym_sec == sec)
667
                    {
668
                      const char *name;
669
                      unsigned char type;
670
                      bfd_vma value;
671
                      bfd_vma baseaddr = BASEADDR (sec);
672
                      bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
673
                        + irel->r_addend;
674
 
675
                      if ((baseaddr + addr) <= symval
676
                          && symval <= (baseaddr + endaddr))
677
                        irel->r_addend += count;
678
 
679
                      /* Go hunt up a function and fix its line info if needed.  */
680
                      stabp = stabcontents + irel->r_offset - 8;
681
 
682
                      /* Go pullout the stab entry.  */
683
                      type  = bfd_h_get_8 (abfd, stabp + TYPEOFF);
684
                      value = bfd_h_get_32 (abfd, stabp + VALOFF);
685
 
686
                      name = bfd_get_stab_name (type);
687
 
688
                      if (strcmp (name, "FUN") == 0)
689
                        {
690
                          int function_adjusted = 0;
691
 
692
                          if (symval > (baseaddr + addr))
693
                            /* Not in this function.  */
694
                            continue;
695
 
696
                          /* Hey we got a function hit.  */
697
                          stabp += STABSIZE;
698
                          for (;stabp < stabend; stabp += STABSIZE)
699
                            {
700
                              /* Go pullout the stab entry.  */
701
                              type  = bfd_h_get_8 (abfd, stabp + TYPEOFF);
702
                              value = bfd_h_get_32 (abfd, stabp + VALOFF);
703
 
704
                              name = bfd_get_stab_name (type);
705
 
706
                              if (strcmp (name, "FUN") == 0)
707
                                {
708
                                  /* Hit another function entry.  */
709
                                  if (function_adjusted)
710
                                    {
711
                                      /* Adjust the value.  */
712
                                      value += count;
713
 
714
                                      /* We need to put it back.  */
715
                                      bfd_h_put_32 (abfd, value,stabp + VALOFF);
716
                                    }
717
 
718
                                  /* And then bale out.  */
719
                                  break;
720
                                }
721
 
722
                              if (strcmp (name, "SLINE") == 0)
723
                                {
724
                                  /* Got a line entry.  */
725
                                  if ((baseaddr + addr) <= (symval + value))
726
                                    {
727
                                      /* Adjust the line entry.  */
728
                                      value += count;
729
 
730
                                      /* We need to put it back.  */
731
                                      bfd_h_put_32 (abfd, value,stabp + VALOFF);
732
                                      function_adjusted = 1;
733
                                    }
734
                                }
735
                            }
736
                        }
737
                    }
738
                }
739
            }
740
        }
741
    }
742
 
743
  /* When adding an instruction back it is sometimes necessary to move any
744
     global or local symbol that was referencing the first instruction of
745
     the moved block to refer to the first instruction of the inserted block.
746
 
747
     For example adding a PAGE instruction before a CALL or JMP requires
748
     that any label on the CALL or JMP is moved to the PAGE insn.  */
749
  addr += noadj;
750
 
751
  /* Adjust the local symbols defined in this section.  */
752
  isymend = isymbuf + symtab_hdr->sh_info;
753
  for (isym = isymbuf; isym < isymend; isym++)
754
    {
755
      if (isym->st_shndx == shndx
756
          && addr <= isym->st_value
757
          && isym->st_value < endaddr)
758
        isym->st_value += count;
759
    }
760
 
761
  /* Now adjust the global symbols defined in this section.  */
762
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
763
              - symtab_hdr->sh_info);
764
  sym_hashes = elf_sym_hashes (abfd);
765
  end_hashes = sym_hashes + symcount;
766
  for (; sym_hashes < end_hashes; sym_hashes++)
767
    {
768
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
769
 
770
      if ((sym_hash->root.type == bfd_link_hash_defined
771
           || sym_hash->root.type == bfd_link_hash_defweak)
772
          && sym_hash->root.u.def.section == sec)
773
        {
774
          if (addr <= sym_hash->root.u.def.value
775
              && sym_hash->root.u.def.value < endaddr)
776
            sym_hash->root.u.def.value += count;
777
        }
778
    }
779
 
780
  return;
781
}
782
 
783
/* Delete some bytes from a section while relaxing.  */
784
 
785
static bfd_boolean
786
ip2k_elf_relax_delete_bytes (bfd *abfd,
787
                             asection *sec,
788
                             bfd_vma addr,
789
                             int count)
790
{
791
  bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
792
  bfd_vma endaddr = sec->size;
793
 
794
  /* Actually delete the bytes.  */
795
  memmove (contents + addr, contents + addr + count,
796
           endaddr - addr - count);
797
 
798
  sec->size -= count;
799
 
800
  adjust_all_relocations (abfd, sec, addr + count, endaddr, -count, 0);
801
  return TRUE;
802
}
803
 
804
static bfd_boolean
805
ip2k_delete_page_insn (bfd *abfd ATTRIBUTE_UNUSED,
806
                       asection *sec,
807
                       Elf_Internal_Rela *irel,
808
                       bfd_boolean *again,
809
                       struct misc *misc)
810
{
811
  /* Note that we've changed the relocs, section contents, etc.  */
812
  elf_section_data (sec)->relocs = misc->irelbase;
813
  elf_section_data (sec)->this_hdr.contents = misc->contents;
814
  misc->symtab_hdr->contents = (bfd_byte *) misc->isymbuf;
815
 
816
  /* Fix the relocation's type.  */
817
  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_IP2K_NONE);
818
 
819
  /* Delete the PAGE insn.  */
820
  if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 2))
821
    return FALSE;
822
 
823
  /* Modified => will need to iterate relaxation again.  */
824
  *again = TRUE;
825
 
826
  return TRUE;
827
}
828
 
829
static bfd_boolean
830
ip2k_relax_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED,
831
                             asection *sec,
832
                             Elf_Internal_Rela *irel,
833
                             bfd_boolean *again,
834
                             struct misc *misc)
835
{
836
  Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
837
  Elf_Internal_Rela *ireltest = irel;
838
  bfd_byte code[4];
839
  bfd_vma addr;
840
 
841
  /* Test all page instructions.  */
842
  addr = irel->r_offset;
843
  while (1)
844
    {
845
      if (addr + 4 > sec->size)
846
        break;
847
 
848
      ip2k_get_mem (abfd, misc->contents + addr, 4, code);
849
      if ((! IS_PAGE_OPCODE (code + 0))
850
          || (! IS_JMP_OPCODE (code + 2)))
851
        break;
852
 
853
      /* Validate relocation entry (every entry should have a matching
854
          relocation entry).  */
855
      if (ireltest >= irelend)
856
        {
857
          _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
858
          return FALSE;
859
        }
860
 
861
      if (ireltest->r_offset != addr)
862
        {
863
          _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
864
          return FALSE;
865
        }
866
 
867
      if (! ip2k_test_page_insn (abfd, sec, ireltest, misc))
868
        /* Un-removable page insn => nothing can be done.  */
869
        return TRUE;
870
 
871
      addr += 4;
872
      ireltest += 2;
873
    }
874
 
875
  /* Relaxable. Adjust table header.  */
876
  ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 4, code);
877
  if ((! IS_ADD_W_WREG_OPCODE (code + 0))
878
      || (! IS_ADD_PCL_W_OPCODE (code + 2)))
879
    {
880
      _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
881
      return FALSE;
882
    }
883
 
884
  if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset - 4, 2))
885
    return FALSE;
886
 
887
  *again = TRUE;
888
 
889
  /* Delete all page instructions in table.  */
890
  while (irel < ireltest)
891
    {
892
      if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
893
        return FALSE;
894
      irel += 2;
895
    }
896
 
897
  return TRUE;
898
}
899
 
900
static bfd_boolean
901
ip2k_relax_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED,
902
                             asection *sec,
903
                             Elf_Internal_Rela *irel,
904
                             bfd_boolean *again,
905
                             struct misc *misc)
906
{
907
  Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
908
  Elf_Internal_Rela *ireltest = irel;
909
  bfd_byte code[12];
910
  bfd_vma addr;
911
 
912
  /* Test all page instructions.  */
913
  addr = irel->r_offset;
914
 
915
  while (1)
916
    {
917
      if (addr + 4 > sec->size)
918
        break;
919
 
920
      ip2k_get_mem (abfd, misc->contents + addr, 4, code);
921
 
922
      if ((! IS_PAGE_OPCODE (code + 0))
923
          || (! IS_JMP_OPCODE (code + 2)))
924
        break;
925
 
926
      /* Validate relocation entry (every entry should have a matching
927
          relocation entry).  */
928
      if (ireltest >= irelend)
929
        {
930
          _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
931
          return FALSE;
932
        }
933
 
934
      if (ireltest->r_offset != addr)
935
        {
936
          _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
937
          return FALSE;
938
        }
939
 
940
      if (!ip2k_test_page_insn (abfd, sec, ireltest, misc))
941
        /* Un-removable page insn => nothing can be done.  */
942
        return TRUE;
943
 
944
      addr += 4;
945
      ireltest += 2;
946
    }
947
 
948
  /* Relaxable. Adjust table header.  */
949
  ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 2, code);
950
  if (IS_PAGE_OPCODE (code))
951
    addr = irel->r_offset - 16;
952
  else
953
    addr = irel->r_offset - 14;
954
 
955
  ip2k_get_mem (abfd, misc->contents + addr, 12, code);
956
  if ((!IS_ADD_W_WREG_OPCODE (code + 0))
957
      || (!IS_SNC_OPCODE (code + 2))
958
      || (!IS_INC_1SP_OPCODE (code + 4))
959
      || (!IS_ADD_2SP_W_OPCODE (code + 6))
960
      || (!IS_SNC_OPCODE (code + 8))
961
      || (!IS_INC_1SP_OPCODE (code + 10)))
962
    {
963
      _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
964
      return FALSE;
965
    }
966
 
967
  /* Delete first 3 opcodes.  */
968
  if (!ip2k_elf_relax_delete_bytes (abfd, sec, addr + 0, 6))
969
    return FALSE;
970
 
971
  *again = TRUE;
972
 
973
  /* Delete all page instructions in table.  */
974
  while (irel < ireltest)
975
    {
976
      if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
977
        return FALSE;
978
      irel += 2;
979
    }
980
 
981
  return TRUE;
982
}
983
 
984
/* This function handles relaxation of a section in a specific page.  */
985
 
986
static bfd_boolean
987
ip2k_elf_relax_section_page (bfd *abfd,
988
                             asection *sec,
989
                             bfd_boolean *again,
990
                             struct misc *misc,
991
                             unsigned long page_start,
992
                             unsigned long page_end)
993
{
994
  Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
995
  Elf_Internal_Rela *irel;
996
  int switch_table_128;
997
  int switch_table_256;
998
 
999
  /* Walk thru the section looking for relaxation opportunities.  */
1000
  for (irel = misc->irelbase; irel < irelend; irel++)
1001
    {
1002
      if (ELF32_R_TYPE (irel->r_info) != (int) R_IP2K_PAGE3)
1003
        /* Ignore non page instructions.  */
1004
        continue;
1005
 
1006
      if (BASEADDR (sec) + irel->r_offset < page_start)
1007
        /* Ignore page instructions on earlier page - they have
1008
           already been processed. Remember that there is code flow
1009
           that crosses a page boundary.  */
1010
        continue;
1011
 
1012
      if (BASEADDR (sec) + irel->r_offset > page_end)
1013
        /* Flow beyond end of page => nothing more to do for this page.  */
1014
        return TRUE;
1015
 
1016
      /* Detect switch tables.  */
1017
      switch_table_128 = ip2k_is_switch_table_128 (abfd, sec, irel->r_offset, misc->contents);
1018
      switch_table_256 = ip2k_is_switch_table_256 (abfd, sec, irel->r_offset, misc->contents);
1019
 
1020
      if ((switch_table_128 > 0) || (switch_table_256 > 0))
1021
        /* If the index is greater than 0 then it has already been processed.  */
1022
        continue;
1023
 
1024
      if (switch_table_128 == 0)
1025
        {
1026
          if (!ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc))
1027
            return FALSE;
1028
 
1029
          continue;
1030
        }
1031
 
1032
      if (switch_table_256 == 0)
1033
        {
1034
          if (!ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc))
1035
            return FALSE;
1036
 
1037
          continue;
1038
        }
1039
 
1040
      /* Simple relax.  */
1041
      if (ip2k_test_page_insn (abfd, sec, irel, misc))
1042
        {
1043
          if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
1044
            return FALSE;
1045
 
1046
          continue;
1047
        }
1048
    }
1049
 
1050
  return TRUE;
1051
}
1052
 
1053
/* This function handles relaxing for the ip2k.
1054
 
1055
   Principle: Start with the first page and remove page instructions that
1056
   are not require on this first page. By removing page instructions more
1057
   code will fit into this page - repeat until nothing more can be achieved
1058
   for this page. Move on to the next page.
1059
 
1060
   Processing the pages one at a time from the lowest page allows a removal
1061
   only policy to be used - pages can be removed but are never reinserted.  */
1062
 
1063
static bfd_boolean
1064
ip2k_elf_relax_section (bfd *abfd,
1065
                        asection *sec,
1066
                        struct bfd_link_info *link_info,
1067
                        bfd_boolean *again)
1068
{
1069
  Elf_Internal_Shdr *symtab_hdr;
1070
  Elf_Internal_Rela *internal_relocs;
1071
  bfd_byte *contents = NULL;
1072
  Elf_Internal_Sym *isymbuf = NULL;
1073
  static asection * first_section = NULL;
1074
  static unsigned long search_addr;
1075
  static unsigned long page_start = 0;
1076
  static unsigned long page_end = 0;
1077
  static unsigned int pass = 0;
1078
  static bfd_boolean new_pass = FALSE;
1079
  static bfd_boolean changed = FALSE;
1080
  struct misc misc;
1081
 
1082
  /* Assume nothing changes.  */
1083
  *again = FALSE;
1084
 
1085
  if (first_section == NULL)
1086
    {
1087
      ip2k_relaxed = TRUE;
1088
      first_section = sec;
1089
    }
1090
 
1091
  if (first_section == sec)
1092
    {
1093
      pass++;
1094
      new_pass = TRUE;
1095
    }
1096
 
1097
  /* We don't have to do anything for a relocatable link,
1098
     if this section does not have relocs, or if this is
1099
     not a code section.  */
1100
  if (link_info->relocatable
1101
      || (sec->flags & SEC_RELOC) == 0
1102
      || sec->reloc_count == 0
1103
      || (sec->flags & SEC_CODE) == 0)
1104
    return TRUE;
1105
 
1106
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1107
 
1108
  internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
1109
                                               link_info->keep_memory);
1110
  if (internal_relocs == NULL)
1111
    goto error_return;
1112
 
1113
  /* Get section contents cached copy if it exists.  */
1114
  if (contents == NULL)
1115
    {
1116
      /* Get cached copy if it exists.  */
1117
      if (elf_section_data (sec)->this_hdr.contents != NULL)
1118
        contents = elf_section_data (sec)->this_hdr.contents;
1119
      else
1120
        {
1121
          /* Go get them off disk.  */
1122
          if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1123
            goto error_return;
1124
        }
1125
    }
1126
 
1127
  /* Read this BFD's symbols cached copy if it exists.  */
1128
  if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1129
    {
1130
      isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1131
      if (isymbuf == NULL)
1132
        isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1133
                                        symtab_hdr->sh_info, 0,
1134
                                        NULL, NULL, NULL);
1135
      if (isymbuf == NULL)
1136
        goto error_return;
1137
    }
1138
 
1139
  misc.symtab_hdr = symtab_hdr;
1140
  misc.isymbuf = isymbuf;
1141
  misc.irelbase = internal_relocs;
1142
  misc.contents = contents;
1143
 
1144
  /* This is where all the relaxation actually get done.  */
1145
  if ((pass == 1) || (new_pass && !changed))
1146
    {
1147
      /* On the first pass we simply search for the lowest page that
1148
         we havn't relaxed yet. Note that the pass count is reset
1149
         each time a page is complete in order to move on to the next page.
1150
         If we can't find any more pages then we are finished.  */
1151
      if (new_pass)
1152
        {
1153
          pass = 1;
1154
          new_pass = FALSE;
1155
          changed = TRUE; /* Pre-initialize to break out of pass 1.  */
1156
          search_addr = 0xFFFFFFFF;
1157
        }
1158
 
1159
      if ((BASEADDR (sec) + sec->size < search_addr)
1160
          && (BASEADDR (sec) + sec->size > page_end))
1161
        {
1162
          if (BASEADDR (sec) <= page_end)
1163
            search_addr = page_end + 1;
1164
          else
1165
            search_addr = BASEADDR (sec);
1166
 
1167
          /* Found a page => more work to do.  */
1168
          *again = TRUE;
1169
        }
1170
    }
1171
  else
1172
    {
1173
      if (new_pass)
1174
        {
1175
          new_pass = FALSE;
1176
          changed = FALSE;
1177
          page_start = PAGENO (search_addr);
1178
          page_end = page_start | 0x00003FFF;
1179
        }
1180
 
1181
      /* Only process sections in range.  */
1182
      if ((BASEADDR (sec) + sec->size >= page_start)
1183
          && (BASEADDR (sec) <= page_end))
1184
        {
1185
          if (!ip2k_elf_relax_section_page (abfd, sec, &changed, &misc, page_start, page_end))
1186
            return FALSE;
1187
        }
1188
      *again = TRUE;
1189
    }
1190
 
1191
  /* Perform some house keeping after relaxing the section.  */
1192
 
1193
  if (isymbuf != NULL
1194
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1195
    {
1196
      if (! link_info->keep_memory)
1197
        free (isymbuf);
1198
      else
1199
        symtab_hdr->contents = (unsigned char *) isymbuf;
1200
    }
1201
 
1202
  if (contents != NULL
1203
      && elf_section_data (sec)->this_hdr.contents != contents)
1204
    {
1205
      if (! link_info->keep_memory)
1206
        free (contents);
1207
      else
1208
        {
1209
          /* Cache the section contents for elf_link_input_bfd.  */
1210
          elf_section_data (sec)->this_hdr.contents = contents;
1211
        }
1212
    }
1213
 
1214
  if (internal_relocs != NULL
1215
      && elf_section_data (sec)->relocs != internal_relocs)
1216
    free (internal_relocs);
1217
 
1218
  return TRUE;
1219
 
1220
 error_return:
1221
  if (isymbuf != NULL
1222
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1223
    free (isymbuf);
1224
  if (contents != NULL
1225
      && elf_section_data (sec)->this_hdr.contents != contents)
1226
    free (contents);
1227
  if (internal_relocs != NULL
1228
      && elf_section_data (sec)->relocs != internal_relocs)
1229
    free (internal_relocs);
1230
  return FALSE;
1231
}
1232
 
1233
/* Set the howto pointer for a IP2K ELF reloc.  */
1234
 
1235
static void
1236
ip2k_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
1237
                         arelent * cache_ptr,
1238
                         Elf_Internal_Rela * dst)
1239
{
1240
  unsigned int r_type;
1241
 
1242
  r_type = ELF32_R_TYPE (dst->r_info);
1243
  cache_ptr->howto = & ip2k_elf_howto_table [r_type];
1244
}
1245
 
1246
/* Perform a single relocation.
1247
   By default we use the standard BFD routines.  */
1248
 
1249
static bfd_reloc_status_type
1250
ip2k_final_link_relocate (reloc_howto_type *  howto,
1251
                          bfd *               input_bfd,
1252
                          asection *          input_section,
1253
                          bfd_byte *          contents,
1254
                          Elf_Internal_Rela * rel,
1255
                          bfd_vma             relocation)
1256
{
1257
  static bfd_vma page_addr = 0;
1258
 
1259
  bfd_reloc_status_type r = bfd_reloc_ok;
1260
  switch (howto->type)
1261
    {
1262
      /* Handle data space relocations.  */
1263
    case R_IP2K_FR9:
1264
    case R_IP2K_BANK:
1265
      if ((relocation & IP2K_DATA_MASK) == IP2K_DATA_VALUE)
1266
        relocation &= ~IP2K_DATA_MASK;
1267
      else
1268
        r = bfd_reloc_notsupported;
1269
      break;
1270
 
1271
    case R_IP2K_LO8DATA:
1272
    case R_IP2K_HI8DATA:
1273
    case R_IP2K_EX8DATA:
1274
      break;
1275
 
1276
      /* Handle insn space relocations.  */
1277
    case R_IP2K_PAGE3:
1278
      page_addr = BASEADDR (input_section) + rel->r_offset;
1279
      if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
1280
        relocation &= ~IP2K_INSN_MASK;
1281
      else
1282
        r = bfd_reloc_notsupported;
1283
      break;
1284
 
1285
    case R_IP2K_ADDR16CJP:
1286
      if (BASEADDR (input_section) + rel->r_offset != page_addr + 2)
1287
        {
1288
          /* No preceding page instruction, verify that it isn't needed.  */
1289
          if (PAGENO (relocation + rel->r_addend) !=
1290
              ip2k_nominal_page_bits (input_bfd, input_section,
1291
                                      rel->r_offset, contents))
1292
            _bfd_error_handler (_("ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."),
1293
                                BASEADDR (input_section) + rel->r_offset,
1294
                                relocation + rel->r_addend);
1295
        }
1296
      else if (ip2k_relaxed)
1297
        {
1298
          /* Preceding page instruction. Verify that the page instruction is
1299
             really needed. One reason for the relaxation to miss a page is if
1300
             the section is not marked as executable.  */
1301
          if (!ip2k_is_switch_table_128 (input_bfd, input_section,
1302
                                         rel->r_offset - 2, contents)
1303
              && !ip2k_is_switch_table_256 (input_bfd, input_section,
1304
                                            rel->r_offset - 2, contents)
1305
              && (PAGENO (relocation + rel->r_addend) ==
1306
                  ip2k_nominal_page_bits (input_bfd, input_section,
1307
                                          rel->r_offset - 2, contents)))
1308
            _bfd_error_handler (_("ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."),
1309
                                page_addr,
1310
                                relocation + rel->r_addend);
1311
        }
1312
      if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
1313
        relocation &= ~IP2K_INSN_MASK;
1314
      else
1315
        r = bfd_reloc_notsupported;
1316
      break;
1317
 
1318
    case R_IP2K_LO8INSN:
1319
    case R_IP2K_HI8INSN:
1320
    case R_IP2K_PC_SKIP:
1321
      if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
1322
        relocation &= ~IP2K_INSN_MASK;
1323
      else
1324
        r = bfd_reloc_notsupported;
1325
      break;
1326
 
1327
    case R_IP2K_16:
1328
      /* If this is a relocation involving a TEXT
1329
         symbol, reduce it to a word address.  */
1330
      if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
1331
        howto = &ip2k_elf_howto_table[ (int) R_IP2K_TEXT];
1332
      break;
1333
 
1334
      /* Pass others through.  */
1335
    default:
1336
      break;
1337
    }
1338
 
1339
  /* Only install relocation if above tests did not disqualify it.  */
1340
  if (r == bfd_reloc_ok)
1341
    r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1342
                                  contents, rel->r_offset,
1343
                                  relocation, rel->r_addend);
1344
 
1345
  return r;
1346
}
1347
 
1348
/* Relocate a IP2K ELF section.
1349
 
1350
   The RELOCATE_SECTION function is called by the new ELF backend linker
1351
   to handle the relocations for a section.
1352
 
1353
   The relocs are always passed as Rela structures; if the section
1354
   actually uses Rel structures, the r_addend field will always be
1355
   zero.
1356
 
1357
   This function is responsible for adjusting the section contents as
1358
   necessary, and (if using Rela relocs and generating a relocatable
1359
   output file) adjusting the reloc addend as necessary.
1360
 
1361
   This function does not have to worry about setting the reloc
1362
   address or the reloc symbol index.
1363
 
1364
   LOCAL_SYMS is a pointer to the swapped in local symbols.
1365
 
1366
   LOCAL_SECTIONS is an array giving the section in the input file
1367
   corresponding to the st_shndx field of each local symbol.
1368
 
1369
   The global hash table entry for the global symbols can be found
1370
   via elf_sym_hashes (input_bfd).
1371
 
1372
   When generating relocatable output, this function must handle
1373
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
1374
   going to be the section symbol corresponding to the output
1375
   section, which means that the addend must be adjusted
1376
   accordingly.  */
1377
 
1378
static bfd_boolean
1379
ip2k_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
1380
                           struct bfd_link_info *info,
1381
                           bfd *input_bfd,
1382
                           asection *input_section,
1383
                           bfd_byte *contents,
1384
                           Elf_Internal_Rela *relocs,
1385
                           Elf_Internal_Sym *local_syms,
1386
                           asection **local_sections)
1387
{
1388
  Elf_Internal_Shdr *symtab_hdr;
1389
  struct elf_link_hash_entry **sym_hashes;
1390
  Elf_Internal_Rela *rel;
1391
  Elf_Internal_Rela *relend;
1392
 
1393
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
1394
  sym_hashes = elf_sym_hashes (input_bfd);
1395
  relend     = relocs + input_section->reloc_count;
1396
 
1397
  for (rel = relocs; rel < relend; rel ++)
1398
    {
1399
      reloc_howto_type *           howto;
1400
      unsigned long                r_symndx;
1401
      Elf_Internal_Sym *           sym;
1402
      asection *                   sec;
1403
      struct elf_link_hash_entry * h;
1404
      bfd_vma                      relocation;
1405
      bfd_reloc_status_type        r;
1406
      const char *                 name = NULL;
1407
      int                          r_type;
1408
 
1409
      r_type = ELF32_R_TYPE (rel->r_info);
1410
      r_symndx = ELF32_R_SYM (rel->r_info);
1411
      howto  = ip2k_elf_howto_table + r_type;
1412
      h      = NULL;
1413
      sym    = NULL;
1414
      sec    = NULL;
1415
 
1416
      if (r_symndx < symtab_hdr->sh_info)
1417
        {
1418
          sym = local_syms + r_symndx;
1419
          sec = local_sections [r_symndx];
1420
          relocation = BASEADDR (sec) + sym->st_value;
1421
 
1422
          name = bfd_elf_string_from_elf_section
1423
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
1424
          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
1425
        }
1426
      else
1427
        {
1428
          bfd_boolean warned;
1429
          bfd_boolean unresolved_reloc;
1430
 
1431
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1432
                                   r_symndx, symtab_hdr, sym_hashes,
1433
                                   h, sec, relocation,
1434
                                   unresolved_reloc, warned);
1435
 
1436
          name = h->root.root.string;
1437
        }
1438
 
1439
      if (sec != NULL && elf_discarded_section (sec))
1440
        {
1441
          /* For relocs against symbols from removed linkonce sections,
1442
             or sections discarded by a linker script, we just want the
1443
             section contents zeroed.  Avoid any special processing.  */
1444
          _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
1445
          rel->r_info = 0;
1446
          rel->r_addend = 0;
1447
          continue;
1448
        }
1449
 
1450
      if (info->relocatable)
1451
        continue;
1452
 
1453
      /* Finally, the sole IP2K-specific part.  */
1454
      r = ip2k_final_link_relocate (howto, input_bfd, input_section,
1455
                                     contents, rel, relocation);
1456
 
1457
      if (r != bfd_reloc_ok)
1458
        {
1459
          const char * msg = NULL;
1460
 
1461
          switch (r)
1462
            {
1463
            case bfd_reloc_overflow:
1464
              r = info->callbacks->reloc_overflow
1465
                (info, (h ? &h->root : NULL), name, howto->name,
1466
                 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
1467
              break;
1468
 
1469
            case bfd_reloc_undefined:
1470
              r = info->callbacks->undefined_symbol
1471
                (info, name, input_bfd, input_section, rel->r_offset, TRUE);
1472
              break;
1473
 
1474
            case bfd_reloc_outofrange:
1475
              msg = _("internal error: out of range error");
1476
              break;
1477
 
1478
              /* This is how ip2k_final_link_relocate tells us of a non-kosher
1479
                 reference between insn & data address spaces.  */
1480
            case bfd_reloc_notsupported:
1481
              if (sym != NULL) /* Only if it's not an unresolved symbol.  */
1482
                 msg = _("unsupported relocation between data/insn address spaces");
1483
              break;
1484
 
1485
            case bfd_reloc_dangerous:
1486
              msg = _("internal error: dangerous relocation");
1487
              break;
1488
 
1489
            default:
1490
              msg = _("internal error: unknown error");
1491
              break;
1492
            }
1493
 
1494
          if (msg)
1495
            r = info->callbacks->warning
1496
              (info, msg, name, input_bfd, input_section, rel->r_offset);
1497
 
1498
          if (! r)
1499
            return FALSE;
1500
        }
1501
    }
1502
 
1503
  return TRUE;
1504
}
1505
 
1506
#define TARGET_BIG_SYM   bfd_elf32_ip2k_vec
1507
#define TARGET_BIG_NAME  "elf32-ip2k"
1508
 
1509
#define ELF_ARCH         bfd_arch_ip2k
1510
#define ELF_MACHINE_CODE EM_IP2K
1511
#define ELF_MACHINE_ALT1 EM_IP2K_OLD
1512
#define ELF_MAXPAGESIZE  1 /* No pages on the IP2K.  */
1513
 
1514
#define elf_info_to_howto_rel                   NULL
1515
#define elf_info_to_howto                       ip2k_info_to_howto_rela
1516
 
1517
#define elf_backend_can_gc_sections             1
1518
#define elf_backend_rela_normal                 1
1519
#define elf_backend_relocate_section            ip2k_elf_relocate_section
1520
 
1521
#define elf_symbol_leading_char                 '_'
1522
#define bfd_elf32_bfd_reloc_type_lookup         ip2k_reloc_type_lookup
1523
#define bfd_elf32_bfd_reloc_name_lookup ip2k_reloc_name_lookup
1524
#define bfd_elf32_bfd_relax_section             ip2k_elf_relax_section
1525
 
1526
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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