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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf32-open8.c] - Blame information for rev 78

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

Line No. Rev Author Line
1 14 khays
/* Open8-specific support for 32-bit ELF
2
   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3
   2009, 2010, 2011  Free Software Foundation, Inc.
4
 
5
   Contributed by Kirk Hays <khays@hayshaus.com>
6
 
7
   This file is part of BFD, the Binary File Descriptor library.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor,
22
   Boston, MA 02110-1301, USA.  */
23
 
24
#include "sysdep.h"
25
#include "bfd.h"
26
#include "libbfd.h"
27
#include "elf-bfd.h"
28
#include "elf/open8.h"
29
#include "elf32-open8.h"
30
 
31
/* Enable debugging printout at stdout with this variable.  */
32
static bfd_boolean debug_relax = FALSE;
33
 
34
/* Enable debugging printout at stdout with this variable.  */
35
static bfd_boolean debug_stubs = FALSE;
36
 
37
/* Hash table initialization and handling.  Code is taken from the hppa port
38
   and adapted to the needs of OPEN8.  */
39
 
40
/* We use two hash tables to hold information for linking open8 objects.
41
 
42
   The first is the elf32_open8_link_hash_table which is derived from the
43
   stanard ELF linker hash table.  We use this as a place to attach the other
44
   hash table and some static information.
45
 
46
   The second is the stub hash table which is derived from the base BFD
47
   hash table.  The stub hash table holds the information on the linker
48
   stubs.  */
49
 
50
struct elf32_open8_stub_hash_entry
51
{
52
  /* Base hash table entry structure.  */
53
  struct bfd_hash_entry bh_root;
54
 
55
  /* Offset within stub_sec of the beginning of this stub.  */
56
  bfd_vma stub_offset;
57
 
58
  /* Given the symbol's value and its section we can determine its final
59
     value when building the stubs (so the stub knows where to jump).  */
60
  bfd_vma target_value;
61
 
62
  /* This way we could mark stubs to be no longer necessary.  */
63
  bfd_boolean is_actually_needed;
64
};
65
 
66
struct elf32_open8_link_hash_table
67
{
68
  /* The main hash table.  */
69
  struct elf_link_hash_table etab;
70
 
71
  /* The stub hash table.  */
72
  struct bfd_hash_table bstab;
73
 
74
  bfd_boolean no_stubs;
75
 
76
  /* Linker stub bfd.  */
77
  bfd *stub_bfd;
78
 
79
  /* The stub section.  */
80
  asection *stub_sec;
81
 
82
  /* Usually 0, unless we are generating code for a bootloader.  Will
83
     be initialized by elf32_open8_size_stubs to the vma offset of the
84
     output section associated with the stub section.  */
85
  bfd_vma vector_base;
86
 
87
  /* Assorted information used by elf32_open8_size_stubs.  */
88
  unsigned int        bfd_count;
89
  int                 top_index;
90
  asection **         input_list;
91
  Elf_Internal_Sym ** all_local_syms;
92
 
93
  /* Tables for mapping vma beyond the 128k boundary to the address of the
94
     corresponding stub.  (AMT)
95
     "amt_max_entry_cnt" reflects the number of entries that memory is allocated
96
     for in the "amt_stub_offsets" and "amt_destination_addr" arrays.
97
     "amt_entry_cnt" informs how many of these entries actually contain
98
     useful data.  */
99
  unsigned int amt_entry_cnt;
100
  unsigned int amt_max_entry_cnt;
101
  bfd_vma *    amt_stub_offsets;
102
  bfd_vma *    amt_destination_addr;
103
};
104
 
105
/* Various hash macros and functions.  */
106
/* PR 3874: Check that we have an OPEN8 style hash table before
107
   using it.  */
108
#define open8_link_hash_table(p)                                        \
109
  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash))       \
110
   == OPEN8_ELF_DATA                                                    \
111
   ? ((struct elf32_open8_link_hash_table *) ((p)->hash))               \
112
   : NULL)
113
 
114
#define open8_stub_hash_entry(ent)              \
115
  ((struct elf32_open8_stub_hash_entry *)(ent))
116
 
117
#define open8_stub_hash_lookup(table, string, create, copy)     \
118
  ((struct elf32_open8_stub_hash_entry *)                       \
119
   bfd_hash_lookup ((table), (string), (create), (copy)))
120
 
121
static reloc_howto_type elf_open8_howto_table[] =
122
  {
123
    HOWTO (R_OPEN8_NONE,
124
           0,
125
           2,
126
           32,
127
           FALSE,
128
           0,
129
           complain_overflow_bitfield,
130
           bfd_elf_generic_reloc,
131
           "R_OPEN8_NONE",
132
           FALSE,
133
           0,
134
           0,
135
           FALSE),
136
 
137
    HOWTO (R_OPEN8_32,
138
           0,
139
           2,
140
           32,
141
           FALSE,
142
           0,
143
           complain_overflow_bitfield,
144
           bfd_elf_generic_reloc,
145
           "R_OPEN8_32",
146
           FALSE,
147
           0xffffffff,
148
           0xffffffff,
149
           FALSE),
150
 
151
    /* An 8 bit PC relative relocation.  */
152
    HOWTO (R_OPEN8_PCREL,
153
           0,
154
           1,
155
           8,
156
           TRUE,
157
           0,
158
           complain_overflow_bitfield,
159
           bfd_elf_generic_reloc,
160
           "R_OPEN8_PCREL",
161
           FALSE,
162
           0xff,
163
           0xff,
164
           TRUE),
165
 
166
    /* A 16 bit absolute relocation.  */
167
    HOWTO (R_OPEN8_16,
168
           0,
169
           1,
170
           16,
171
           FALSE,
172
           0,
173
           complain_overflow_dont,
174
           bfd_elf_generic_reloc,
175
           "R_OPEN8_16",
176
           FALSE,
177
           0xffff,
178
           0xffff,
179
           FALSE),
180
 
181
    /* A low 8 bit absolute relocation of 16 bit address.
182
       For LDI command.  */
183
    HOWTO (R_OPEN8_LO8_LDI,
184
           0,
185
           1,
186
           8,
187
           FALSE,
188
           0,
189
           complain_overflow_dont,
190
           bfd_elf_generic_reloc,
191
           "R_OPEN8_LO8_LDI",
192
           FALSE,
193
           0xffff,
194
           0xffff,
195
           FALSE),
196
 
197
    /* A high 8 bit absolute relocation of 16 bit address.
198
       For LDI command.  */
199
    HOWTO (R_OPEN8_HI8_LDI,
200
           8,
201
           1,
202
           8,
203
           FALSE,
204
           0,
205
           complain_overflow_dont,
206
           bfd_elf_generic_reloc,
207
           "R_OPEN8_HI8_LDI",
208
           FALSE,
209
           0xffff,
210
           0xffff,
211
           FALSE),
212
    /* A negative low 8 bit absolute relocation of 16 bit address.
213
       For LDI command.  */
214
    HOWTO (R_OPEN8_LO8_LDI_NEG,
215
           0,
216
           1,
217
           8,
218
           FALSE,
219
           0,
220
           complain_overflow_dont,
221
           bfd_elf_generic_reloc,
222
           "R_OPEN8_LO8_LDI_NEG",
223
           FALSE,
224
           0xffff,
225
           0xffff,
226
           FALSE),
227
 
228
    /* A negative high 8 bit absolute relocation of 16 bit address.
229
       For LDI command.  */
230
    HOWTO (R_OPEN8_HI8_LDI_NEG,
231
           8,
232
           1,
233
           8,
234
           FALSE,
235
           0,
236
           complain_overflow_dont,
237
           bfd_elf_generic_reloc,
238
           "R_OPEN8_HI8_LDI_NEG",
239
           FALSE,
240
           0xffff,
241
           0xffff,
242
           FALSE),
243
 
244
    /* Relocation for JSR and JMP in OPEN8.  */
245
    HOWTO (R_OPEN8_CALL,
246
           0,
247
           2,
248
           16,
249
           FALSE,
250
           0,
251
           complain_overflow_dont,
252
           bfd_elf_generic_reloc,
253
           "R_OPEN8_CALL",
254
           FALSE,
255
           0xffffffff,
256
           0xffffffff,
257
           FALSE),
258
 
259
    /* 8 bit offset.  */
260
    HOWTO (R_OPEN8_8,
261
           0,
262
           0,
263
           8,
264
           FALSE,
265
           0,
266
           complain_overflow_bitfield,
267
           bfd_elf_generic_reloc,
268
           "R_OPEN8_8",
269
           FALSE,
270
           0x000000ff,
271
           0x000000ff,
272
           FALSE),
273
  };
274
 
275
/* Map BFD reloc types to OPEN8 ELF reloc types.  */
276
 
277
struct open8_reloc_map
278
{
279
  bfd_reloc_code_real_type bfd_reloc_val;
280
  unsigned int elf_reloc_val;
281
};
282
 
283
static const struct open8_reloc_map open8_reloc_map[] =
284
  {
285
    { BFD_RELOC_NONE,                 R_OPEN8_NONE },
286
    { BFD_RELOC_32,                   R_OPEN8_32 },
287
    { BFD_RELOC_OPEN8_PCREL,          R_OPEN8_PCREL },
288
    { BFD_RELOC_16,                   R_OPEN8_16 },
289
    { BFD_RELOC_OPEN8_LO8_LDI,          R_OPEN8_LO8_LDI},
290
    { BFD_RELOC_OPEN8_HI8_LDI,          R_OPEN8_HI8_LDI },
291
    { BFD_RELOC_OPEN8_LO8_LDI_NEG,      R_OPEN8_LO8_LDI_NEG },
292
    { BFD_RELOC_OPEN8_HI8_LDI_NEG,      R_OPEN8_HI8_LDI_NEG },
293
    { BFD_RELOC_OPEN8_CALL,             R_OPEN8_CALL },
294
    { BFD_RELOC_8,                    R_OPEN8_8 }
295
  };
296
 
297
/* Meant to be filled one day with the wrap around address for the
298
   specific device.  I.e., should get the value 0x4000 for 16k devices,
299
   0x8000 for 32k devices and so on.
300
 
301
   We initialize it here with a value of 0x1000000 resulting in
302
   that we will never suggest a wrap-around jump during relaxation.
303
   The logic of the source code later on assumes that in
304
   open8_pc_wrap_around one single bit is set.  */
305
static bfd_vma open8_pc_wrap_around = 0x10000000;
306
 
307
/* If this variable holds a value different from zero, the linker relaxation
308
   machine will try to optimize call/ret sequences by a single jump
309
   instruction.  This option could be switched off by a linker switch.  */
310
static int open8_replace_call_ret_sequences = 1;
311
 
312
/* Initialize an entry in the stub hash table.  */
313
 
314
static struct bfd_hash_entry *
315
stub_hash_newfunc (struct bfd_hash_entry *entry,
316
                   struct bfd_hash_table *table,
317
                   const char *string)
318
{
319
  /* Allocate the structure if it has not already been allocated by a
320
     subclass.  */
321
  if (entry == NULL)
322
    {
323
      entry = bfd_hash_allocate (table,
324
                                 sizeof (struct elf32_open8_stub_hash_entry));
325
      if (entry == NULL)
326
        return entry;
327
    }
328
 
329
  /* Call the allocation method of the superclass.  */
330
  entry = bfd_hash_newfunc (entry, table, string);
331
  if (entry != NULL)
332
    {
333
      struct elf32_open8_stub_hash_entry *hsh;
334
 
335
      /* Initialize the local fields.  */
336
      hsh = open8_stub_hash_entry (entry);
337
      hsh->stub_offset = 0;
338
      hsh->target_value = 0;
339
    }
340
 
341
  return entry;
342
}
343
 
344
/* This function is just a straight passthrough to the real
345
   function in linker.c.  Its purpose is so that its address
346
   can be compared inside the open8_link_hash_table macro.  */
347
 
348
static struct bfd_hash_entry *
349
elf32_open8_link_hash_newfunc (struct bfd_hash_entry * entry,
350
                               struct bfd_hash_table * table,
351
                               const char * string)
352
{
353
  return _bfd_elf_link_hash_newfunc (entry, table, string);
354
}
355
 
356
/* Create the derived linker hash table.  The OPEN8 ELF port uses the derived
357
   hash table to keep information specific to the OPEN8 ELF linker (without
358
   using static variables).  */
359
 
360
static struct bfd_link_hash_table *
361
elf32_open8_link_hash_table_create (bfd *abfd)
362
{
363
  struct elf32_open8_link_hash_table *htab;
364
  bfd_size_type amt = sizeof (*htab);
365
 
366
  htab = bfd_malloc (amt);
367
  if (htab == NULL)
368
    return NULL;
369
 
370
  if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd,
371
                                      elf32_open8_link_hash_newfunc,
372
                                      sizeof (struct elf_link_hash_entry),
373
                                      OPEN8_ELF_DATA))
374
    {
375
      free (htab);
376
      return NULL;
377
    }
378
 
379
  /* Init the stub hash table too.  */
380
  if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc,
381
                            sizeof (struct elf32_open8_stub_hash_entry)))
382
    return NULL;
383
 
384
  htab->stub_bfd = NULL;
385
  htab->stub_sec = NULL;
386
 
387
  /* Initialize the address mapping table.  */
388
  htab->amt_stub_offsets = NULL;
389
  htab->amt_destination_addr = NULL;
390
  htab->amt_entry_cnt = 0;
391
  htab->amt_max_entry_cnt = 0;
392
 
393
  return &htab->etab.root;
394
}
395
 
396
/* Free the derived linker hash table.  */
397
 
398
static void
399
elf32_open8_link_hash_table_free (struct bfd_link_hash_table *btab)
400
{
401
  struct elf32_open8_link_hash_table *htab
402
    = (struct elf32_open8_link_hash_table *) btab;
403
 
404
  /* Free the address mapping table.  */
405
  if (htab->amt_stub_offsets != NULL)
406
    free (htab->amt_stub_offsets);
407
  if (htab->amt_destination_addr != NULL)
408
    free (htab->amt_destination_addr);
409
 
410
  bfd_hash_table_free (&htab->bstab);
411
  _bfd_generic_link_hash_table_free (btab);
412
}
413
 
414
static reloc_howto_type *
415
bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
416
                                 bfd_reloc_code_real_type code)
417
{
418
  unsigned int i;
419
 
420
  for (i = 0;
421
       i < sizeof (open8_reloc_map) / sizeof (struct open8_reloc_map);
422
       i++)
423
    if (open8_reloc_map[i].bfd_reloc_val == code)
424
      return &elf_open8_howto_table[open8_reloc_map[i].elf_reloc_val];
425
 
426
  return NULL;
427
}
428
 
429
static reloc_howto_type *
430
bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
431
                                 const char *r_name)
432
{
433
  unsigned int i;
434
 
435
  for (i = 0;
436
       i < sizeof (elf_open8_howto_table) / sizeof (elf_open8_howto_table[0]);
437
       i++)
438
    if (elf_open8_howto_table[i].name != NULL
439
        && strcasecmp (elf_open8_howto_table[i].name, r_name) == 0)
440
      return &elf_open8_howto_table[i];
441
 
442
  return NULL;
443
}
444
 
445
/* Set the howto pointer for an OPEN8 ELF reloc.  */
446
 
447
static void
448
open8_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
449
                          arelent *cache_ptr,
450
                          Elf_Internal_Rela *dst)
451
{
452
  unsigned int r_type;
453
 
454
  r_type = ELF32_R_TYPE (dst->r_info);
455
  BFD_ASSERT (r_type < (unsigned int) R_OPEN8_max);
456
  cache_ptr->howto = &elf_open8_howto_table[r_type];
457
}
458
 
459
static bfd_boolean
460
open8_stub_is_required_for_16_bit_reloc (bfd_vma relocation)
461
{
462
  return (relocation >= 0x020000);
463
}
464
 
465
/* Perform a single relocation.  By default we use the standard BFD
466
   routines, but a few relocs, we have to do them ourselves.  */
467
 
468
static bfd_reloc_status_type
469
open8_final_link_relocate (reloc_howto_type *                 howto,
470
                           bfd *                              input_bfd,
471
                           asection *                         input_section,
472
                           bfd_byte *                         contents,
473
                           Elf_Internal_Rela *                rel,
474
                           bfd_vma                            relocation)
475
{
476
  bfd_reloc_status_type r = bfd_reloc_ok;
477
  bfd_vma               x;
478
  bfd_signed_vma        srel;
479
  bfd_signed_vma        reloc_addr;
480
 
481
  /* Absolute addr of the reloc in the final excecutable.  */
482
  reloc_addr = rel->r_offset + input_section->output_section->vma
483
    + input_section->output_offset;
484
 
485
  switch (howto->type)
486
    {
487
    case R_OPEN8_PCREL:
488
      contents += rel->r_offset;
489
      srel = (bfd_signed_vma) relocation;
490
      srel += rel->r_addend;
491
 
492
      if (srel > ((1 << 8) - 1) || (srel < - (1 << 7)))
493
        return bfd_reloc_overflow;
494
      x = bfd_get_16 (input_bfd, contents);
495
      x = (x & 0xff00) | (srel & 0xff);
496
      bfd_put_16 (input_bfd, x, contents);
497
      break;
498
 
499
    case R_OPEN8_CALL:
500
      contents += rel->r_offset;
501
      srel = (bfd_signed_vma) relocation + rel->r_addend;
502
      bfd_put_16 (input_bfd, srel, contents);
503
      break;
504
 
505
    case R_OPEN8_LO8_LDI:
506
      contents += rel->r_offset;
507
      srel = (bfd_signed_vma) relocation + rel->r_addend;
508
      x = bfd_get_16 (input_bfd, contents);
509
      x = (x & 0xff00) | (srel & 0x0ff);
510
      bfd_put_16 (input_bfd, x, contents);
511
      break;
512
 
513
    case R_OPEN8_HI8_LDI:
514
      contents += rel->r_offset;
515
      srel = (bfd_signed_vma) relocation + rel->r_addend;
516
      x = bfd_get_16 (input_bfd, contents);
517
      x = (x & 0xff00) | ((srel >> 4) & 0x0ff);
518
      bfd_put_16 (input_bfd, x, contents);
519
      break;
520
 
521
    case R_OPEN8_LO8_LDI_NEG:
522
      contents += rel->r_offset;
523
      srel = (bfd_signed_vma) relocation + rel->r_addend;
524
      srel = -srel;
525
      x = bfd_get_16 (input_bfd, contents);
526
      x = (x & 0xff00) | (srel & 0x0ff);
527
      bfd_put_16 (input_bfd, x, contents);
528
      break;
529
 
530
    case R_OPEN8_HI8_LDI_NEG:
531
      contents += rel->r_offset;
532
      srel = (bfd_signed_vma) relocation + rel->r_addend;
533
      srel = -srel;
534
      x = bfd_get_16 (input_bfd, contents);
535
      x = (x & 0xff00) | ((srel >> 4) & 0x0ff);
536
      bfd_put_16 (input_bfd, x, contents);
537
      break;
538
 
539
    default:
540
      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
541
                                    contents, rel->r_offset,
542
                                    relocation, rel->r_addend);
543
    }
544
 
545
  return r;
546
}
547
 
548
/* Relocate an OPEN8 ELF section.  */
549
 
550
static bfd_boolean
551
elf32_open8_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
552
                              struct bfd_link_info *info,
553
                              bfd *input_bfd,
554
                              asection *input_section,
555
                              bfd_byte *contents,
556
                              Elf_Internal_Rela *relocs,
557
                              Elf_Internal_Sym *local_syms,
558
                              asection **local_sections)
559
{
560
  Elf_Internal_Shdr *           symtab_hdr;
561
  struct elf_link_hash_entry ** sym_hashes;
562
  Elf_Internal_Rela *           rel;
563
  Elf_Internal_Rela *           relend;
564
  struct elf32_open8_link_hash_table * htab = open8_link_hash_table (info);
565
 
566
  if (htab == NULL)
567
    return FALSE;
568
 
569
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
570
  sym_hashes = elf_sym_hashes (input_bfd);
571
  relend     = relocs + input_section->reloc_count;
572
 
573
  for (rel = relocs; rel < relend; rel ++)
574
    {
575
      reloc_howto_type *           howto;
576
      unsigned long                r_symndx;
577
      Elf_Internal_Sym *           sym;
578
      asection *                   sec;
579
      struct elf_link_hash_entry * h;
580
      bfd_vma                      relocation;
581
      bfd_reloc_status_type        r;
582
      const char *                 name;
583
      int                          r_type;
584
 
585
      r_type = ELF32_R_TYPE (rel->r_info);
586
      r_symndx = ELF32_R_SYM (rel->r_info);
587
      howto  = elf_open8_howto_table + r_type;
588
      h      = NULL;
589
      sym    = NULL;
590
      sec    = NULL;
591
 
592
      if (r_symndx < symtab_hdr->sh_info)
593
        {
594
          sym = local_syms + r_symndx;
595
          sec = local_sections [r_symndx];
596
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
597
 
598
          name = bfd_elf_string_from_elf_section
599
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
600
          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
601
        }
602
      else
603
        {
604
          bfd_boolean unresolved_reloc, warned;
605
 
606
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
607
                                   r_symndx, symtab_hdr, sym_hashes,
608
                                   h, sec, relocation,
609
                                   unresolved_reloc, warned);
610
 
611
          name = h->root.root.string;
612
        }
613
 
614
      if (sec != NULL && elf_discarded_section (sec))
615
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
616
                                         rel, relend, howto, contents);
617
 
618
      if (info->relocatable)
619
        continue;
620
 
621
      r = open8_final_link_relocate (howto, input_bfd, input_section,
622
                                     contents, rel, relocation);
623
 
624
      if (r != bfd_reloc_ok)
625
        {
626
          const char * msg = (const char *) NULL;
627
 
628
          switch (r)
629
            {
630
            case bfd_reloc_overflow:
631
              r = info->callbacks->reloc_overflow
632
                (info, (h ? &h->root : NULL),
633
                 name, howto->name, (bfd_vma) 0,
634
                 input_bfd, input_section, rel->r_offset);
635
              break;
636
 
637
            case bfd_reloc_undefined:
638
              r = info->callbacks->undefined_symbol
639
                (info, name, input_bfd, input_section, rel->r_offset, TRUE);
640
              break;
641
 
642
            case bfd_reloc_outofrange:
643
              msg = _("internal error: out of range error");
644
              break;
645
 
646
            case bfd_reloc_notsupported:
647
              msg = _("internal error: unsupported relocation error");
648
              break;
649
 
650
            case bfd_reloc_dangerous:
651
              msg = _("internal error: dangerous relocation");
652
              break;
653
 
654
            default:
655
              msg = _("internal error: unknown error");
656
              break;
657
            }
658
 
659
          if (msg)
660
            r = info->callbacks->warning
661
              (info, msg, name, input_bfd, input_section, rel->r_offset);
662
 
663
          if (! r)
664
            return FALSE;
665
        }
666
    }
667
 
668
  return TRUE;
669
}
670
 
671
/* The final processing done just before writing out a OPEN8 ELF object
672
   file.  This gets the OPEN8 architecture right based on the machine
673
   number.  */
674
 
675
static void
676
bfd_elf_open8_final_write_processing (bfd *abfd,
677
                                      bfd_boolean linker ATTRIBUTE_UNUSED)
678
{
679
  unsigned long val;
680
 
681
  switch (bfd_get_mach (abfd))
682
    {
683
    default:
684
    case bfd_mach_open8_1:
685
      val = E_OPEN8_MACH_OPEN8_1;
686
      break;
687
    }
688
 
689
  elf_elfheader (abfd)->e_machine = EM_OPEN8;
690
  elf_elfheader (abfd)->e_flags &= ~ EF_OPEN8_MACH;
691
  elf_elfheader (abfd)->e_flags |= val;
692
  elf_elfheader (abfd)->e_flags |= EF_OPEN8_LINKRELAX_PREPARED;
693
}
694
 
695
/* Set the right machine number.  */
696
 
697
static bfd_boolean
698
elf32_open8_object_p (bfd *abfd)
699
{
700
  unsigned int e_set = bfd_mach_open8_1;
701
 
702
  if (elf_elfheader (abfd)->e_machine == EM_OPEN8)
703
    {
704
      int e_mach = elf_elfheader (abfd)->e_flags & EF_OPEN8_MACH;
705
 
706
      switch (e_mach)
707
        {
708
        default:
709
        case E_OPEN8_MACH_OPEN8_1:
710
          e_set = bfd_mach_open8_1;
711
          break;
712
 
713
        }
714
    }
715
  return bfd_default_set_arch_mach (abfd, bfd_arch_open8,
716
                                    e_set);
717
}
718
 
719
 
720
/* Delete some bytes from a section while changing the size of an instruction.
721
   The parameter "addr" denotes the section-relative offset pointing just
722
   behind the shrinked instruction. "addr+count" point at the first
723
   byte just behind the original unshrinked instruction.  */
724
 
725
static bfd_boolean
726
elf32_open8_relax_delete_bytes (bfd *abfd,
727
                                asection *sec,
728
                                bfd_vma addr,
729
                                int count)
730
{
731
  Elf_Internal_Shdr *symtab_hdr;
732
  unsigned int sec_shndx;
733
  bfd_byte *contents;
734
  Elf_Internal_Rela *irel, *irelend;
735
  Elf_Internal_Sym *isym;
736
  Elf_Internal_Sym *isymbuf = NULL;
737
  bfd_vma toaddr;
738
  struct elf_link_hash_entry **sym_hashes;
739
  struct elf_link_hash_entry **end_hashes;
740
  unsigned int symcount;
741
 
742
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
743
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
744
  contents = elf_section_data (sec)->this_hdr.contents;
745
 
746
  toaddr = sec->size;
747
 
748
  irel = elf_section_data (sec)->relocs;
749
  irelend = irel + sec->reloc_count;
750
 
751
  /* Actually delete the bytes.  */
752
  if (toaddr - addr - count > 0)
753
    memmove (contents + addr, contents + addr + count,
754
             (size_t) (toaddr - addr - count));
755
  sec->size -= count;
756
 
757
  /* Adjust all the reloc addresses.  */
758
  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
759
    {
760
      bfd_vma old_reloc_address;
761
 
762
      old_reloc_address = (sec->output_section->vma
763
                           + sec->output_offset + irel->r_offset);
764
 
765
      /* Get the new reloc address.  */
766
      if ((irel->r_offset > addr
767
           && irel->r_offset < toaddr))
768
        {
769
          if (debug_relax)
770
            printf ("Relocation at address 0x%x needs to be moved.\n"
771
                    "Old section offset: 0x%x, New section offset: 0x%x \n",
772
                    (unsigned int) old_reloc_address,
773
                    (unsigned int) irel->r_offset,
774
                    (unsigned int) ((irel->r_offset) - count));
775
 
776
          irel->r_offset -= count;
777
        }
778
 
779
    }
780
 
781
  /* The reloc's own addresses are now ok.  However, we need to readjust
782
     the reloc's addend, i.e., the reloc's value if two conditions are met:
783
     1.) the reloc is relative to a symbol in this section that
784
     is located in front of the shrinked instruction
785
     2.) symbol plus addend end up behind the shrinked instruction.
786
 
787
     The most common case where this happens are relocs relative to
788
     the section-start symbol.
789
 
790
     This step needs to be done for all of the sections of the bfd.  */
791
 
792
  {
793
    struct bfd_section *isec;
794
 
795
    for (isec = abfd->sections; isec; isec = isec->next)
796
      {
797
        bfd_vma symval;
798
        bfd_vma shrinked_insn_address;
799
 
800
        shrinked_insn_address = (sec->output_section->vma
801
                                 + sec->output_offset + addr - count);
802
 
803
        irelend = elf_section_data (isec)->relocs + isec->reloc_count;
804
        for (irel = elf_section_data (isec)->relocs;
805
             irel < irelend;
806
             irel++)
807
          {
808
            /* Read this BFD's local symbols if we haven't done
809
               so already.  */
810
            if (isymbuf == NULL && symtab_hdr->sh_info != 0)
811
              {
812
                isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
813
                if (isymbuf == NULL)
814
                  isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
815
                                                  symtab_hdr->sh_info, 0,
816
                                                  NULL, NULL, NULL);
817
                if (isymbuf == NULL)
818
                  return FALSE;
819
              }
820
 
821
            /* Get the value of the symbol referred to by the reloc.  */
822
            if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
823
              {
824
                /* A local symbol.  */
825
                asection *sym_sec;
826
 
827
                isym = isymbuf + ELF32_R_SYM (irel->r_info);
828
                sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
829
                symval = isym->st_value;
830
                /* If the reloc is absolute, it will not have
831
                   a symbol or section associated with it.  */
832
                if (sym_sec == sec)
833
                  {
834
                    symval += sym_sec->output_section->vma
835
                      + sym_sec->output_offset;
836
 
837
                    if (debug_relax)
838
                      printf ("Checking if the relocation's "
839
                              "addend needs corrections.\n"
840
                              "Address of anchor symbol: 0x%x \n"
841
                              "Address of relocation target: 0x%x \n"
842
                              "Address of relaxed insn: 0x%x \n",
843
                              (unsigned int) symval,
844
                              (unsigned int) (symval + irel->r_addend),
845
                              (unsigned int) shrinked_insn_address);
846
 
847
                    if (symval <= shrinked_insn_address
848
                        && (symval + irel->r_addend) > shrinked_insn_address)
849
                      {
850
                        irel->r_addend -= count;
851
 
852
                        if (debug_relax)
853
                          printf ("Relocation's addend needed to be fixed \n");
854
                      }
855
                  }
856
                /* else, reference symbol is absolute.
857
                   No adjustment needed.  */
858
              }
859
            /* else, reference symbol is extern.  No need for adjusting
860
               the addend.  */
861
          }
862
      }
863
  }
864
 
865
  /* Adjust the local symbols defined in this section.  */
866
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
867
  /* Fix PR 9841, there may be no local symbols.  */
868
  if (isym != NULL)
869
    {
870
      Elf_Internal_Sym *isymend;
871
 
872
      isymend = isym + symtab_hdr->sh_info;
873
      for (; isym < isymend; isym++)
874
        {
875
          if (isym->st_shndx == sec_shndx
876
              && isym->st_value > addr
877
              && isym->st_value < toaddr)
878
            isym->st_value -= count;
879
        }
880
    }
881
 
882
  /* Now adjust the global symbols defined in this section.  */
883
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
884
              - symtab_hdr->sh_info);
885
  sym_hashes = elf_sym_hashes (abfd);
886
  end_hashes = sym_hashes + symcount;
887
  for (; sym_hashes < end_hashes; sym_hashes++)
888
    {
889
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
890
      if ((sym_hash->root.type == bfd_link_hash_defined
891
           || sym_hash->root.type == bfd_link_hash_defweak)
892
          && sym_hash->root.u.def.section == sec
893
          && sym_hash->root.u.def.value > addr
894
          && sym_hash->root.u.def.value < toaddr)
895
        {
896
          sym_hash->root.u.def.value -= count;
897
        }
898
    }
899
 
900
  return TRUE;
901
}
902
 
903
/* This function handles relaxing for the open8.
904
   Many important relaxing opportunities within functions are already
905
   realized by the compiler itself.
906
   Here we try to replace branch followed by jump with a reverse branch.
907
   As well we now optimize sequences of
908
   - call/rcall function
909
   - ret
910
   to yield
911
   - jmp/ function
912
   - ret
913
   . In case that within a sequence
914
   - jmp/rjmp label
915
   - ret
916
   the ret could no longer be reached it is optimized away.  In order
917
   to check if the ret is no longer needed, it is checked that the ret's address
918
   is not the target of a branch or jump within the same section, it is checked
919
   that there is no skip instruction before the jmp/rjmp and that there
920
   is no local or global label placed at the address of the ret.
921
 
922
   We refrain from relaxing within sections ".vectors" and
923
   ".jumptables" in order to maintain the position of the instructions.
924
   There, however, we substitute jmp/call by a sequence rjmp,nop/rcall,nop
925
   if possible. (In the future, one could possibly use the space of the nop
926
   for the first instruction of the irq service function.)
927
 
928
*/
929
 
930
static bfd_boolean
931
elf32_open8_relax_section (bfd *abfd,
932
                           asection *sec,
933
                           struct bfd_link_info *link_info,
934
                           bfd_boolean *again)
935
{
936
  Elf_Internal_Shdr *symtab_hdr;
937
  Elf_Internal_Rela *internal_relocs;
938
  Elf_Internal_Rela *irel, *irelend;
939
  bfd_byte *contents = NULL;
940
  Elf_Internal_Sym *isymbuf = NULL;
941
  struct elf32_open8_link_hash_table *htab;
942
 
943
  if (link_info->relocatable)
944
    (*link_info->callbacks->einfo)
945
      (_("%P%F: --relax and -r may not be used together\n"));
946
 
947
/* TODO - MAJOR REWORK NEEDED HERE!!!
948
   This code is AVR relaxation, need open8 version.  */
949
  return FALSE;
950
 
951
  htab = open8_link_hash_table (link_info);
952
  if (htab == NULL)
953
    return FALSE;
954
 
955
  /* Assume nothing changes.  */
956
  *again = FALSE;
957
 
958
  if ((!htab->no_stubs) && (sec == htab->stub_sec))
959
    {
960
      /* We are just relaxing the stub section.
961
         Let's calculate the size needed again.  */
962
      bfd_size_type last_estimated_stub_section_size = htab->stub_sec->size;
963
 
964
      if (debug_relax)
965
        printf ("Relaxing the stub section.  Size prior to this pass: %i\n",
966
                (int) last_estimated_stub_section_size);
967
 
968
      elf32_open8_size_stubs (htab->stub_sec->output_section->owner,
969
                              link_info, FALSE);
970
 
971
      /* Check if the number of trampolines changed.  */
972
      if (last_estimated_stub_section_size != htab->stub_sec->size)
973
        *again = TRUE;
974
 
975
      if (debug_relax)
976
        printf ("Size of stub section after this pass: %i\n",
977
                (int) htab->stub_sec->size);
978
 
979
      return TRUE;
980
    }
981
 
982
  /* We don't have to do anything for a relocatable link, if
983
     this section does not have relocs, or if this is not a
984
     code section.  */
985
  if (link_info->relocatable
986
      || (sec->flags & SEC_RELOC) == 0
987
      || sec->reloc_count == 0
988
      || (sec->flags & SEC_CODE) == 0)
989
    return TRUE;
990
 
991
  /* Check if the object file to relax uses internal symbols so that we
992
     could fix up the relocations.  */
993
  if (!(elf_elfheader (abfd)->e_flags & EF_OPEN8_LINKRELAX_PREPARED))
994
    return TRUE;
995
 
996
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
997
 
998
  /* Get a copy of the native relocations.  */
999
  internal_relocs = (_bfd_elf_link_read_relocs
1000
                     (abfd, sec, NULL, NULL, link_info->keep_memory));
1001
  if (internal_relocs == NULL)
1002
    goto error_return;
1003
 
1004
  /* Walk through the relocs looking for relaxing opportunities.  */
1005
  irelend = internal_relocs + sec->reloc_count;
1006
  for (irel = internal_relocs; irel < irelend; irel++)
1007
    {
1008
      bfd_vma symval;
1009
 
1010
      if (   ELF32_R_TYPE (irel->r_info) != R_OPEN8_PCREL
1011
             && ELF32_R_TYPE (irel->r_info) != R_OPEN8_CALL)
1012
        continue;
1013
 
1014
      /* Get the section contents if we haven't done so already.  */
1015
      if (contents == NULL)
1016
        {
1017
          /* Get cached copy if it exists.  */
1018
          if (elf_section_data (sec)->this_hdr.contents != NULL)
1019
            contents = elf_section_data (sec)->this_hdr.contents;
1020
          else
1021
            {
1022
              /* Go get them off disk.  */
1023
              if (! bfd_malloc_and_get_section (abfd, sec, &contents))
1024
                goto error_return;
1025
            }
1026
        }
1027
 
1028
      /* Read this BFD's local symbols if we haven't done so already.  */
1029
      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1030
        {
1031
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1032
          if (isymbuf == NULL)
1033
            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1034
                                            symtab_hdr->sh_info, 0,
1035
                                            NULL, NULL, NULL);
1036
          if (isymbuf == NULL)
1037
            goto error_return;
1038
        }
1039
 
1040
 
1041
      /* Get the value of the symbol referred to by the reloc.  */
1042
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1043
        {
1044
          /* A local symbol.  */
1045
          Elf_Internal_Sym *isym;
1046
          asection *sym_sec;
1047
 
1048
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
1049
          sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1050
          symval = isym->st_value;
1051
          /* If the reloc is absolute, it will not have
1052
             a symbol or section associated with it.  */
1053
          if (sym_sec)
1054
            symval += sym_sec->output_section->vma
1055
              + sym_sec->output_offset;
1056
        }
1057
      else
1058
        {
1059
          unsigned long indx;
1060
          struct elf_link_hash_entry *h;
1061
 
1062
          /* An external symbol.  */
1063
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1064
          h = elf_sym_hashes (abfd)[indx];
1065
          BFD_ASSERT (h != NULL);
1066
          if (h->root.type != bfd_link_hash_defined
1067
              && h->root.type != bfd_link_hash_defweak)
1068
            /* This appears to be a reference to an undefined
1069
               symbol.  Just ignore it--it will be caught by the
1070
               regular reloc processing.  */
1071
            continue;
1072
 
1073
          symval = (h->root.u.def.value
1074
                    + h->root.u.def.section->output_section->vma
1075
                    + h->root.u.def.section->output_offset);
1076
        }
1077
 
1078
      /* For simplicity of coding, we are going to modify the section
1079
         contents, the section relocs, and the BFD symbol table.  We
1080
         must tell the rest of the code not to free up this
1081
         information.  It would be possible to instead create a table
1082
         of changes which have to be made, as is done in coff-mips.c;
1083
         that would be more work, but would require less memory when
1084
         the linker is run.  */
1085
      switch (ELF32_R_TYPE (irel->r_info))
1086
        {
1087
 
1088
        default:
1089
          {
1090
            unsigned char code_msb;
1091
            unsigned char code_lsb;
1092
            bfd_vma dot;
1093
 
1094
            code_msb = bfd_get_8 (abfd, contents + irel->r_offset + 1);
1095
            code_lsb = bfd_get_8 (abfd, contents + irel->r_offset + 0);
1096
 
1097
            /* Get the address of this instruction.  */
1098
            dot = (sec->output_section->vma
1099
                   + sec->output_offset + irel->r_offset);
1100
 
1101
            /* Here we look for rcall/ret or call/ret sequences that could be
1102
               safely replaced by rjmp/ret or jmp/ret.  */
1103
            if (((code_msb & 0xf0) == 0xd0)
1104
                && open8_replace_call_ret_sequences)
1105
              {
1106
                /* This insn is a rcall.  */
1107
                unsigned char next_insn_msb = 0;
1108
                unsigned char next_insn_lsb = 0;
1109
 
1110
                if (irel->r_offset + 3 < sec->size)
1111
                  {
1112
                    next_insn_msb =
1113
                      bfd_get_8 (abfd, contents + irel->r_offset + 3);
1114
                    next_insn_lsb =
1115
                      bfd_get_8 (abfd, contents + irel->r_offset + 2);
1116
                  }
1117
 
1118
                if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
1119
                  {
1120
                    /* The next insn is a ret.  We now convert the rcall insn
1121
                       into a rjmp instruction.  */
1122
                    code_msb &= 0xef;
1123
                    bfd_put_8 (abfd, code_msb, contents + irel->r_offset + 1);
1124
                    if (debug_relax)
1125
                      printf ("converted rcall/ret sequence at address 0x%x"
1126
                              " into rjmp/ret sequence.  Section is %s\n\n",
1127
                              (int) dot, sec->name);
1128
                    *again = TRUE;
1129
                    break;
1130
                  }
1131
              }
1132
            else if ((0x94 == (code_msb & 0xfe))
1133
                     && (0x0e == (code_lsb & 0x0e))
1134
                     && open8_replace_call_ret_sequences)
1135
              {
1136
                /* This insn is a call.  */
1137
                unsigned char next_insn_msb = 0;
1138
                unsigned char next_insn_lsb = 0;
1139
 
1140
                if (irel->r_offset + 5 < sec->size)
1141
                  {
1142
                    next_insn_msb =
1143
                      bfd_get_8 (abfd, contents + irel->r_offset + 5);
1144
                    next_insn_lsb =
1145
                      bfd_get_8 (abfd, contents + irel->r_offset + 4);
1146
                  }
1147
 
1148
                if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
1149
                  {
1150
                    /* The next insn is a ret.  We now convert the call insn
1151
                       into a jmp instruction.  */
1152
 
1153
                    code_lsb &= 0xfd;
1154
                    bfd_put_8 (abfd, code_lsb, contents + irel->r_offset);
1155
                    if (debug_relax)
1156
                      printf ("converted call/ret sequence at address 0x%x"
1157
                              " into jmp/ret sequence.  Section is %s\n\n",
1158
                              (int) dot, sec->name);
1159
                    *again = TRUE;
1160
                    break;
1161
                  }
1162
              }
1163
            else if ((0xc0 == (code_msb & 0xf0))
1164
                     || ((0x94 == (code_msb & 0xfe))
1165
                         && (0x0c == (code_lsb & 0x0e))))
1166
              {
1167
                /* This insn is a rjmp or a jmp.  */
1168
                unsigned char next_insn_msb = 0;
1169
                unsigned char next_insn_lsb = 0;
1170
                int insn_size;
1171
 
1172
                if (0xc0 == (code_msb & 0xf0))
1173
                  insn_size = 2;
1174
                else
1175
                  insn_size = 4;
1176
 
1177
                if (irel->r_offset + insn_size + 1 < sec->size)
1178
                  {
1179
                    next_insn_msb =
1180
                      bfd_get_8 (abfd, contents + irel->r_offset
1181
                                 + insn_size + 1);
1182
                    next_insn_lsb =
1183
                      bfd_get_8 (abfd, contents + irel->r_offset
1184
                                 + insn_size);
1185
                  }
1186
 
1187
                if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
1188
                  {
1189
                    /* The next insn is a ret.  We possibly could delete
1190
                       this ret.  First we need to check for preceeding
1191
                       sbis/sbic/sbrs or cpse "skip" instructions.  */
1192
 
1193
                    int there_is_preceeding_non_skip_insn = 1;
1194
                    bfd_vma address_of_ret;
1195
 
1196
                    address_of_ret = dot + insn_size;
1197
 
1198
                    if (debug_relax && (insn_size == 2))
1199
                      printf ("found rjmp / ret sequence at address 0x%x\n",
1200
                              (int) dot);
1201
                    if (debug_relax && (insn_size == 4))
1202
                      printf ("found jmp / ret sequence at address 0x%x\n",
1203
                              (int) dot);
1204
 
1205
                    /* We have to make sure that there is a preceeding insn.  */
1206
                    if (irel->r_offset >= 2)
1207
                      {
1208
                        unsigned char preceeding_msb;
1209
                        unsigned char preceeding_lsb;
1210
                        preceeding_msb =
1211
                          bfd_get_8 (abfd, contents + irel->r_offset - 1);
1212
                        preceeding_lsb =
1213
                          bfd_get_8 (abfd, contents + irel->r_offset - 2);
1214
 
1215
                        /* sbic.  */
1216
                        if (0x99 == preceeding_msb)
1217
                          there_is_preceeding_non_skip_insn = 0;
1218
 
1219
                        /* sbis.  */
1220
                        if (0x9b == preceeding_msb)
1221
                          there_is_preceeding_non_skip_insn = 0;
1222
 
1223
                        /* sbrc.  */
1224
                        if ((0xfc == (preceeding_msb & 0xfe)
1225
                             && (0x00 == (preceeding_lsb & 0x08))))
1226
                          there_is_preceeding_non_skip_insn = 0;
1227
 
1228
                        /* sbrs.  */
1229
                        if ((0xfe == (preceeding_msb & 0xfe)
1230
                             && (0x00 == (preceeding_lsb & 0x08))))
1231
                          there_is_preceeding_non_skip_insn = 0;
1232
 
1233
                        /* cpse.  */
1234
                        if (0x10 == (preceeding_msb & 0xfc))
1235
                          there_is_preceeding_non_skip_insn = 0;
1236
 
1237
                        if (there_is_preceeding_non_skip_insn == 0)
1238
                          if (debug_relax)
1239
                            printf ("preceeding skip insn prevents deletion of"
1240
                                    " ret insn at addr 0x%x in section %s\n",
1241
                                    (int) dot + 2, sec->name);
1242
                      }
1243
                    else
1244
                      {
1245
                        /* There is no previous instruction.  */
1246
                        there_is_preceeding_non_skip_insn = 0;
1247
                      }
1248
 
1249
                    if (there_is_preceeding_non_skip_insn)
1250
                      {
1251
                        /* We now only have to make sure that there is no
1252
                           local label defined at the address of the ret
1253
                           instruction and that there is no local relocation
1254
                           in this section pointing to the ret.  */
1255
 
1256
                        int deleting_ret_is_safe = 1;
1257
                        unsigned int section_offset_of_ret_insn =
1258
                          irel->r_offset + insn_size;
1259
                        Elf_Internal_Sym *isym, *isymend;
1260
                        unsigned int sec_shndx;
1261
 
1262
                        sec_shndx =
1263
                          _bfd_elf_section_from_bfd_section (abfd, sec);
1264
 
1265
                        /* Check for local symbols.  */
1266
                        isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1267
                        isymend = isym + symtab_hdr->sh_info;
1268
                        /* PR 6019: There may not be any local symbols.  */
1269
                        for (; isym != NULL && isym < isymend; isym++)
1270
                          {
1271
                            if (isym->st_value == section_offset_of_ret_insn
1272
                                && isym->st_shndx == sec_shndx)
1273
                              {
1274
                                deleting_ret_is_safe = 0;
1275
                                if (debug_relax)
1276
                                  printf ("local label prevents deletion of"
1277
                                          "ret insn at address 0x%x\n",
1278
                                          (int) dot + insn_size);
1279
                              }
1280
                          }
1281
 
1282
                        /* Now check for global symbols.  */
1283
                        {
1284
                          int symcount;
1285
                          struct elf_link_hash_entry **sym_hashes;
1286
                          struct elf_link_hash_entry **end_hashes;
1287
 
1288
                          symcount = (symtab_hdr->sh_size
1289
                                      / sizeof (Elf32_External_Sym)
1290
                                      - symtab_hdr->sh_info);
1291
                          sym_hashes = elf_sym_hashes (abfd);
1292
                          end_hashes = sym_hashes + symcount;
1293
                          for (; sym_hashes < end_hashes; sym_hashes++)
1294
                            {
1295
                              struct elf_link_hash_entry *sym_hash =
1296
                                *sym_hashes;
1297
                              if ((sym_hash->root.type == bfd_link_hash_defined
1298
                                   || sym_hash->root.type ==
1299
                                   bfd_link_hash_defweak)
1300
                                  && sym_hash->root.u.def.section == sec
1301
                                  && (sym_hash->root.u.def.value
1302
                                      == section_offset_of_ret_insn))
1303
                                {
1304
                                  deleting_ret_is_safe = 0;
1305
                                  if (debug_relax)
1306
                                    printf ("global label prevents deletion of "
1307
                                            "ret insn at address 0x%x\n",
1308
                                            (int) dot + insn_size);
1309
                                }
1310
                            }
1311
                        }
1312
                        /* Now we check for relocations pointing to ret.  */
1313
                        {
1314
                          Elf_Internal_Rela *rel;
1315
                          Elf_Internal_Rela *relend;
1316
 
1317
                          relend = elf_section_data (sec)->relocs
1318
                            + sec->reloc_count;
1319
 
1320
                          for (rel = elf_section_data (sec)->relocs;
1321
                               rel < relend; rel++)
1322
                            {
1323
                              bfd_vma reloc_target = 0;
1324
 
1325
                              /* Read this BFD's local symbols if we haven't
1326
                                 done so already.  */
1327
                              if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1328
                                {
1329
                                  isymbuf = (Elf_Internal_Sym *)
1330
                                    symtab_hdr->contents;
1331
                                  if (isymbuf == NULL)
1332
                                    isymbuf = bfd_elf_get_elf_syms
1333
                                      (abfd,
1334
                                       symtab_hdr,
1335
                                       symtab_hdr->sh_info, 0,
1336
                                       NULL, NULL, NULL);
1337
                                  if (isymbuf == NULL)
1338
                                    break;
1339
                                }
1340
 
1341
                              /* Get the value of the symbol referred to
1342
                                 by the reloc.  */
1343
                              if (ELF32_R_SYM (rel->r_info)
1344
                                  < symtab_hdr->sh_info)
1345
                                {
1346
                                  /* A local symbol.  */
1347
                                  asection *sym_sec;
1348
 
1349
                                  isym = isymbuf
1350
                                    + ELF32_R_SYM (rel->r_info);
1351
                                  sym_sec = bfd_section_from_elf_index
1352
                                    (abfd, isym->st_shndx);
1353
                                  symval = isym->st_value;
1354
 
1355
                                  /* If the reloc is absolute, it will not
1356
                                     have a symbol or section associated
1357
                                     with it.  */
1358
 
1359
                                  if (sym_sec)
1360
                                    {
1361
                                      symval +=
1362
                                        sym_sec->output_section->vma
1363
                                        + sym_sec->output_offset;
1364
                                      reloc_target = symval + rel->r_addend;
1365
                                    }
1366
                                  else
1367
                                    {
1368
                                      reloc_target = symval + rel->r_addend;
1369
                                      /* Reference symbol is absolute.  */
1370
                                    }
1371
                                }
1372
                              /* else, reference symbol is extern.  */
1373
 
1374
                              if (address_of_ret == reloc_target)
1375
                                {
1376
                                  deleting_ret_is_safe = 0;
1377
                                  if (debug_relax)
1378
                                    printf ("ret from "
1379
                                            "rjmp/jmp ret sequence at address"
1380
                                            " 0x%x could not be deleted.  ret"
1381
                                            " is target of a relocation.\n",
1382
                                            (int) address_of_ret);
1383
                                }
1384
                            }
1385
                        }
1386
 
1387
                        if (deleting_ret_is_safe)
1388
                          {
1389
                            if (debug_relax)
1390
                              printf ("unreachable ret instruction "
1391
                                      "at address 0x%x deleted.\n",
1392
                                      (int) dot + insn_size);
1393
 
1394
                            /* Delete two bytes of data.  */
1395
                            if (!elf32_open8_relax_delete_bytes (abfd,
1396
                                                                 sec,
1397
                                                                 irel->r_offset
1398
                                                                 + insn_size,
1399
                                                                 2))
1400
                              goto error_return;
1401
 
1402
                            /* That will change things, so, we should relax
1403
                               again.  Note that this is not required, and it
1404
                               may be slow.  */
1405
                            *again = TRUE;
1406
                            break;
1407
                          }
1408
                      }
1409
 
1410
                  }
1411
              }
1412
            break;
1413
          }
1414
        }
1415
    }
1416
 
1417
  if (contents != NULL
1418
      && elf_section_data (sec)->this_hdr.contents != contents)
1419
    {
1420
      if (! link_info->keep_memory)
1421
        free (contents);
1422
      else
1423
        {
1424
          /* Cache the section contents for elf_link_input_bfd.  */
1425
          elf_section_data (sec)->this_hdr.contents = contents;
1426
        }
1427
    }
1428
 
1429
  if (internal_relocs != NULL
1430
      && elf_section_data (sec)->relocs != internal_relocs)
1431
    free (internal_relocs);
1432
 
1433
  return TRUE;
1434
 
1435
 error_return:
1436
  if (isymbuf != NULL
1437
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1438
    free (isymbuf);
1439
  if (contents != NULL
1440
      && elf_section_data (sec)->this_hdr.contents != contents)
1441
    free (contents);
1442
  if (internal_relocs != NULL
1443
      && elf_section_data (sec)->relocs != internal_relocs)
1444
    free (internal_relocs);
1445
 
1446
  return FALSE;
1447
}
1448
 
1449
/* This is a version of bfd_generic_get_relocated_section_contents
1450
   which uses elf32_open8_relocate_section.
1451
 
1452
   For open8 it's essentially a cut and paste taken from the H8300 port.
1453
   The author of the relaxation support patch for open8 had absolutely no
1454
   clue what is happening here but found out that this part of the code
1455
   seems to be important.  */
1456
 
1457
static bfd_byte *
1458
elf32_open8_get_relocated_section_contents (bfd *output_bfd,
1459
                                            struct bfd_link_info *link_info,
1460
                                            struct bfd_link_order *link_order,
1461
                                            bfd_byte *data,
1462
                                            bfd_boolean relocatable,
1463
                                            asymbol **symbols)
1464
{
1465
  Elf_Internal_Shdr *symtab_hdr;
1466
  asection *input_section = link_order->u.indirect.section;
1467
  bfd *input_bfd = input_section->owner;
1468
  asection **sections = NULL;
1469
  Elf_Internal_Rela *internal_relocs = NULL;
1470
  Elf_Internal_Sym *isymbuf = NULL;
1471
 
1472
  /* We only need to handle the case of relaxing, or of having a
1473
     particular set of section contents, specially.  */
1474
  if (relocatable
1475
      || elf_section_data (input_section)->this_hdr.contents == NULL)
1476
    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1477
                                                       link_order, data,
1478
                                                       relocatable,
1479
                                                       symbols);
1480
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1481
 
1482
  memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1483
          (size_t) input_section->size);
1484
 
1485
  if ((input_section->flags & SEC_RELOC) != 0
1486
      && input_section->reloc_count > 0)
1487
    {
1488
      asection **secpp;
1489
      Elf_Internal_Sym *isym, *isymend;
1490
      bfd_size_type amt;
1491
 
1492
      internal_relocs = (_bfd_elf_link_read_relocs
1493
                         (input_bfd, input_section, NULL, NULL, FALSE));
1494
      if (internal_relocs == NULL)
1495
        goto error_return;
1496
 
1497
      if (symtab_hdr->sh_info != 0)
1498
        {
1499
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1500
          if (isymbuf == NULL)
1501
            isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1502
                                            symtab_hdr->sh_info, 0,
1503
                                            NULL, NULL, NULL);
1504
          if (isymbuf == NULL)
1505
            goto error_return;
1506
        }
1507
 
1508
      amt = symtab_hdr->sh_info;
1509
      amt *= sizeof (asection *);
1510
      sections = bfd_malloc (amt);
1511
      if (sections == NULL && amt != 0)
1512
        goto error_return;
1513
 
1514
      isymend = isymbuf + symtab_hdr->sh_info;
1515
      for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1516
        {
1517
          asection *isec;
1518
 
1519
          if (isym->st_shndx == SHN_UNDEF)
1520
            isec = bfd_und_section_ptr;
1521
          else if (isym->st_shndx == SHN_ABS)
1522
            isec = bfd_abs_section_ptr;
1523
          else if (isym->st_shndx == SHN_COMMON)
1524
            isec = bfd_com_section_ptr;
1525
          else
1526
            isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1527
 
1528
          *secpp = isec;
1529
        }
1530
 
1531
      if (! elf32_open8_relocate_section (output_bfd, link_info, input_bfd,
1532
                                          input_section, data, internal_relocs,
1533
                                          isymbuf, sections))
1534
        goto error_return;
1535
 
1536
      if (sections != NULL)
1537
        free (sections);
1538
      if (isymbuf != NULL
1539
          && symtab_hdr->contents != (unsigned char *) isymbuf)
1540
        free (isymbuf);
1541
      if (elf_section_data (input_section)->relocs != internal_relocs)
1542
        free (internal_relocs);
1543
    }
1544
 
1545
  return data;
1546
 
1547
 error_return:
1548
  if (sections != NULL)
1549
    free (sections);
1550
  if (isymbuf != NULL
1551
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1552
    free (isymbuf);
1553
  if (internal_relocs != NULL
1554
      && elf_section_data (input_section)->relocs != internal_relocs)
1555
    free (internal_relocs);
1556
  return NULL;
1557
}
1558
 
1559
 
1560
/* Determines the hash entry name for a particular reloc.  It consists of
1561
   the identifier of the symbol section and the added reloc addend and
1562
   symbol offset relative to the section the symbol is attached to.  */
1563
 
1564
static char *
1565
open8_stub_name (const asection *symbol_section,
1566
                 const bfd_vma symbol_offset,
1567
                 const Elf_Internal_Rela *rela)
1568
{
1569
  char *stub_name;
1570
  bfd_size_type len;
1571
 
1572
  len = 8 + 1 + 8 + 1 + 1;
1573
  stub_name = bfd_malloc (len);
1574
 
1575
  snprintf (stub_name, len, "%08x+%08x",
1576
            symbol_section->id & 0xffffffff,
1577
            (unsigned int) ((rela->r_addend & 0xffffffff) + symbol_offset));
1578
 
1579
  return stub_name;
1580
}
1581
 
1582
 
1583
/* Add a new stub entry to the stub hash.  Not all fields of the new
1584
   stub entry are initialised.  */
1585
 
1586
static struct elf32_open8_stub_hash_entry *
1587
open8_add_stub (const char *stub_name,
1588
                struct elf32_open8_link_hash_table *htab)
1589
{
1590
  struct elf32_open8_stub_hash_entry *hsh;
1591
 
1592
  /* Enter this entry into the linker stub hash table.  */
1593
  hsh = open8_stub_hash_lookup (&htab->bstab, stub_name, TRUE, FALSE);
1594
 
1595
  if (hsh == NULL)
1596
    {
1597
      (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
1598
                             NULL, stub_name);
1599
      return NULL;
1600
    }
1601
 
1602
  hsh->stub_offset = 0;
1603
  return hsh;
1604
}
1605
 
1606
/* We assume that there is already space allocated for the stub section
1607
   contents and that before building the stubs the section size is
1608
   initialized to 0.  We assume that within the stub hash table entry,
1609
   the absolute position of the jmp target has been written in the
1610
   target_value field.  We write here the offset of the generated jmp insn
1611
   relative to the trampoline section start to the stub_offset entry in
1612
   the stub hash table entry.  */
1613
 
1614
static  bfd_boolean
1615
open8_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
1616
{
1617
  struct elf32_open8_stub_hash_entry *hsh;
1618
  struct bfd_link_info *info;
1619
  struct elf32_open8_link_hash_table *htab;
1620
  bfd *stub_bfd;
1621
  bfd_byte *loc;
1622
  bfd_vma target;
1623
  bfd_vma starget;
1624
 
1625
  /* Basic opcode.  */
1626
  bfd_vma jmp_insn = 0x0000940c;
1627
 
1628
  /* Massage our args to the form they really have.  */
1629
  hsh = open8_stub_hash_entry (bh);
1630
 
1631
  if (!hsh->is_actually_needed)
1632
    return TRUE;
1633
 
1634
  info = (struct bfd_link_info *) in_arg;
1635
 
1636
  htab = open8_link_hash_table (info);
1637
  if (htab == NULL)
1638
    return FALSE;
1639
 
1640
  target = hsh->target_value;
1641
 
1642
  /* Make a note of the offset within the stubs for this entry.  */
1643
  hsh->stub_offset = htab->stub_sec->size;
1644
  loc = htab->stub_sec->contents + hsh->stub_offset;
1645
 
1646
  stub_bfd = htab->stub_sec->owner;
1647
 
1648
  if (debug_stubs)
1649
    printf ("Building one Stub.  Address: 0x%x, Offset: 0x%x\n",
1650
            (unsigned int) target,
1651
            (unsigned int) hsh->stub_offset);
1652
 
1653
  /* We now have to add the information on the jump target to the bare
1654
     opcode bits already set in jmp_insn.  */
1655
 
1656
  /* Check for the alignment of the address.  */
1657
  if (target & 1)
1658
    return FALSE;
1659
 
1660
  starget = target >> 1;
1661
  jmp_insn |= ((starget & 0x10000) | ((starget << 3) & 0x1f00000)) >> 16;
1662
  bfd_put_16 (stub_bfd, jmp_insn, loc);
1663
  bfd_put_16 (stub_bfd, (bfd_vma) starget & 0xffff, loc + 2);
1664
 
1665
  htab->stub_sec->size += 4;
1666
 
1667
  /* Now add the entries in the address mapping table if there is still
1668
     space left.  */
1669
  {
1670
    unsigned int nr;
1671
 
1672
    nr = htab->amt_entry_cnt + 1;
1673
    if (nr <= htab->amt_max_entry_cnt)
1674
      {
1675
        htab->amt_entry_cnt = nr;
1676
 
1677
        htab->amt_stub_offsets[nr - 1] = hsh->stub_offset;
1678
        htab->amt_destination_addr[nr - 1] = target;
1679
      }
1680
  }
1681
 
1682
  return TRUE;
1683
}
1684
 
1685
static bfd_boolean
1686
open8_mark_stub_not_to_be_necessary (struct bfd_hash_entry *bh,
1687
                                     void *in_arg ATTRIBUTE_UNUSED)
1688
{
1689
  struct elf32_open8_stub_hash_entry *hsh;
1690
 
1691
  hsh = open8_stub_hash_entry (bh);
1692
  hsh->is_actually_needed = FALSE;
1693
 
1694
  return TRUE;
1695
}
1696
 
1697
static bfd_boolean
1698
open8_size_one_stub (struct bfd_hash_entry *bh, void *in_arg)
1699
{
1700
  struct elf32_open8_stub_hash_entry *hsh;
1701
  struct elf32_open8_link_hash_table *htab;
1702
  int size;
1703
 
1704
  /* Massage our args to the form they really have.  */
1705
  hsh = open8_stub_hash_entry (bh);
1706
  htab = in_arg;
1707
 
1708
  if (hsh->is_actually_needed)
1709
    size = 4;
1710
  else
1711
    size = 0;
1712
 
1713
  htab->stub_sec->size += size;
1714
  return TRUE;
1715
}
1716
 
1717
void
1718
elf32_open8_setup_params (struct bfd_link_info *info,
1719
                          bfd *open8_stub_bfd,
1720
                          asection *open8_stub_section,
1721
                          bfd_boolean no_stubs,
1722
                          bfd_boolean deb_stubs,
1723
                          bfd_boolean deb_relax,
1724
                          bfd_vma pc_wrap_around,
1725
                          bfd_boolean call_ret_replacement)
1726
{
1727
  struct elf32_open8_link_hash_table *htab = open8_link_hash_table (info);
1728
 
1729
  if (htab == NULL)
1730
    return;
1731
  htab->stub_sec = open8_stub_section;
1732
  htab->stub_bfd = open8_stub_bfd;
1733
  htab->no_stubs = no_stubs;
1734
 
1735
  debug_relax = deb_relax;
1736
  debug_stubs = deb_stubs;
1737
  open8_pc_wrap_around = pc_wrap_around;
1738
  open8_replace_call_ret_sequences = call_ret_replacement;
1739
}
1740
 
1741
 
1742
/* Set up various things so that we can make a list of input sections
1743
   for each output section included in the link.  Returns -1 on error,
1744
 
1745
   information on the stubs bfd and the stub section in the info
1746
   struct.  */
1747
 
1748
int
1749
elf32_open8_setup_section_lists (bfd *output_bfd,
1750
                                 struct bfd_link_info *info)
1751
{
1752
  bfd *input_bfd;
1753
  unsigned int bfd_count;
1754
  int top_id, top_index;
1755
  asection *section;
1756
  asection **input_list, **list;
1757
  bfd_size_type amt;
1758
  struct elf32_open8_link_hash_table *htab = open8_link_hash_table (info);
1759
 
1760
  if (htab == NULL || htab->no_stubs)
1761
    return 0;
1762
 
1763
  /* Count the number of input BFDs and find the top input section id.  */
1764
  for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
1765
       input_bfd != NULL;
1766
       input_bfd = input_bfd->link_next)
1767
    {
1768
      bfd_count += 1;
1769
      for (section = input_bfd->sections;
1770
           section != NULL;
1771
           section = section->next)
1772
        if (top_id < section->id)
1773
          top_id = section->id;
1774
    }
1775
 
1776
  htab->bfd_count = bfd_count;
1777
 
1778
  /* We can't use output_bfd->section_count here to find the top output
1779
     section index as some sections may have been removed, and
1780
     strip_excluded_output_sections doesn't renumber the indices.  */
1781
  for (section = output_bfd->sections, top_index = 0;
1782
       section != NULL;
1783
       section = section->next)
1784
    if (top_index < section->index)
1785
      top_index = section->index;
1786
 
1787
  htab->top_index = top_index;
1788
  amt = sizeof (asection *) * (top_index + 1);
1789
  input_list = bfd_malloc (amt);
1790
  htab->input_list = input_list;
1791
  if (input_list == NULL)
1792
    return -1;
1793
 
1794
  /* For sections we aren't interested in, mark their entries with a
1795
     value we can check later.  */
1796
  list = input_list + top_index;
1797
  do
1798
    *list = bfd_abs_section_ptr;
1799
  while (list-- != input_list);
1800
 
1801
  for (section = output_bfd->sections;
1802
       section != NULL;
1803
       section = section->next)
1804
    if ((section->flags & SEC_CODE) != 0)
1805
      input_list[section->index] = NULL;
1806
 
1807
  return 1;
1808
}
1809
 
1810
 
1811
/* Read in all local syms for all input bfds, and create hash entries
1812
   for export stubs if we are building a multi-subspace shared lib.
1813
   Returns -1 on error, 0 otherwise.  */
1814
 
1815
static int
1816
get_local_syms (bfd *input_bfd, struct bfd_link_info *info)
1817
{
1818
  unsigned int bfd_indx;
1819
  Elf_Internal_Sym *local_syms, **all_local_syms;
1820
  struct elf32_open8_link_hash_table *htab = open8_link_hash_table (info);
1821
  bfd_size_type amt;
1822
 
1823
  if (htab == NULL)
1824
    return -1;
1825
 
1826
  /* We want to read in symbol extension records only once.  To do this
1827
     we need to read in the local symbols in parallel and save them for
1828
     later use; so hold pointers to the local symbols in an array.  */
1829
  amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
1830
  all_local_syms = bfd_zmalloc (amt);
1831
  htab->all_local_syms = all_local_syms;
1832
  if (all_local_syms == NULL)
1833
    return -1;
1834
 
1835
  /* Walk over all the input BFDs, swapping in local symbols.
1836
     If we are creating a shared library, create hash entries for the
1837
     export stubs.  */
1838
  for (bfd_indx = 0;
1839
       input_bfd != NULL;
1840
       input_bfd = input_bfd->link_next, bfd_indx++)
1841
    {
1842
      Elf_Internal_Shdr *symtab_hdr;
1843
 
1844
      /* We'll need the symbol table in a second.  */
1845
      symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1846
      if (symtab_hdr->sh_info == 0)
1847
        continue;
1848
 
1849
      /* We need an array of the local symbols attached to the input bfd.  */
1850
      local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
1851
      if (local_syms == NULL)
1852
        {
1853
          local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1854
                                             symtab_hdr->sh_info, 0,
1855
                                             NULL, NULL, NULL);
1856
          /* Cache them for elf_link_input_bfd.  */
1857
          symtab_hdr->contents = (unsigned char *) local_syms;
1858
        }
1859
      if (local_syms == NULL)
1860
        return -1;
1861
 
1862
      all_local_syms[bfd_indx] = local_syms;
1863
    }
1864
 
1865
  return 0;
1866
}
1867
 
1868
#define ADD_DUMMY_STUBS_FOR_DEBUGGING 0
1869
 
1870
bfd_boolean
1871
elf32_open8_size_stubs (bfd *output_bfd,
1872
                        struct bfd_link_info *info,
1873
                        bfd_boolean is_prealloc_run)
1874
{
1875
  struct elf32_open8_link_hash_table *htab;
1876
  int stub_changed = 0;
1877
 
1878
  htab = open8_link_hash_table (info);
1879
  if (htab == NULL)
1880
    return FALSE;
1881
 
1882
  /* At this point we initialize htab->vector_base
1883
     To the start of the text output section.  */
1884
  htab->vector_base = htab->stub_sec->output_section->vma;
1885
 
1886
  if (get_local_syms (info->input_bfds, info))
1887
    {
1888
      if (htab->all_local_syms)
1889
        goto error_ret_free_local;
1890
      return FALSE;
1891
    }
1892
 
1893
  if (ADD_DUMMY_STUBS_FOR_DEBUGGING)
1894
    {
1895
      struct elf32_open8_stub_hash_entry *test;
1896
 
1897
      test = open8_add_stub ("Hugo",htab);
1898
      test->target_value = 0x123456;
1899
      test->stub_offset = 13;
1900
 
1901
      test = open8_add_stub ("Hugo2",htab);
1902
      test->target_value = 0x84210;
1903
      test->stub_offset = 14;
1904
    }
1905
 
1906
  while (1)
1907
    {
1908
      bfd *input_bfd;
1909
      unsigned int bfd_indx;
1910
 
1911
      /* We will have to re-generate the stub hash table each time anything
1912
         in memory has changed.  */
1913
 
1914
      bfd_hash_traverse (&htab->bstab,
1915
                         open8_mark_stub_not_to_be_necessary,
1916
                         htab);
1917
      for (input_bfd = info->input_bfds, bfd_indx = 0;
1918
           input_bfd != NULL;
1919
           input_bfd = input_bfd->link_next, bfd_indx++)
1920
        {
1921
          Elf_Internal_Shdr *symtab_hdr;
1922
          asection *section;
1923
          Elf_Internal_Sym *local_syms;
1924
 
1925
          /* We'll need the symbol table in a second.  */
1926
          symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1927
          if (symtab_hdr->sh_info == 0)
1928
            continue;
1929
 
1930
          local_syms = htab->all_local_syms[bfd_indx];
1931
 
1932
          /* Walk over each section attached to the input bfd.  */
1933
          for (section = input_bfd->sections;
1934
               section != NULL;
1935
               section = section->next)
1936
            {
1937
              Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
1938
 
1939
              /* If there aren't any relocs, then there's nothing more
1940
                 to do.  */
1941
              if ((section->flags & SEC_RELOC) == 0
1942
                  || section->reloc_count == 0)
1943
                continue;
1944
 
1945
              /* If this section is a link-once section that will be
1946
                 discarded, then don't create any stubs.  */
1947
              if (section->output_section == NULL
1948
                  || section->output_section->owner != output_bfd)
1949
                continue;
1950
 
1951
              /* Get the relocs.  */
1952
              internal_relocs = _bfd_elf_link_read_relocs (input_bfd,
1953
                                                           section,
1954
                                                           NULL,
1955
                                                           NULL,
1956
                                                           info->keep_memory);
1957
              if (internal_relocs == NULL)
1958
                goto error_ret_free_local;
1959
 
1960
              /* Now examine each relocation.  */
1961
              irela = internal_relocs;
1962
              irelaend = irela + section->reloc_count;
1963
              for (; irela < irelaend; irela++)
1964
                {
1965
                  unsigned int r_type, r_indx;
1966
                  struct elf32_open8_stub_hash_entry *hsh;
1967
                  asection *sym_sec;
1968
                  bfd_vma sym_value;
1969
                  bfd_vma destination;
1970
                  struct elf_link_hash_entry *hh;
1971
                  char *stub_name;
1972
 
1973
                  r_type = ELF32_R_TYPE (irela->r_info);
1974
                  r_indx = ELF32_R_SYM (irela->r_info);
1975
 
1976
                  /* Now determine the call target, its name, value,
1977
                     section.  */
1978
                  sym_sec = NULL;
1979
                  sym_value = 0;
1980
                  destination = 0;
1981
                  hh = NULL;
1982
                  if (r_indx < symtab_hdr->sh_info)
1983
                    {
1984
                      /* It's a local symbol.  */
1985
                      Elf_Internal_Sym *sym;
1986
                      Elf_Internal_Shdr *hdr;
1987
                      unsigned int shndx;
1988
 
1989
                      sym = local_syms + r_indx;
1990
                      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
1991
                        sym_value = sym->st_value;
1992
                      shndx = sym->st_shndx;
1993
                      if (shndx < elf_numsections (input_bfd))
1994
                        {
1995
                          hdr = elf_elfsections (input_bfd)[shndx];
1996
                          sym_sec = hdr->bfd_section;
1997
                          destination = (sym_value + irela->r_addend
1998
                                         + sym_sec->output_offset
1999
                                         + sym_sec->output_section->vma);
2000
                        }
2001
                    }
2002
                  else
2003
                    {
2004
                      /* It's an external symbol.  */
2005
                      int e_indx;
2006
 
2007
                      e_indx = r_indx - symtab_hdr->sh_info;
2008
                      hh = elf_sym_hashes (input_bfd)[e_indx];
2009
 
2010
                      while (hh->root.type == bfd_link_hash_indirect
2011
                             || hh->root.type == bfd_link_hash_warning)
2012
                        hh = (struct elf_link_hash_entry *)
2013
                          (hh->root.u.i.link);
2014
 
2015
                      if (hh->root.type == bfd_link_hash_defined
2016
                          || hh->root.type == bfd_link_hash_defweak)
2017
                        {
2018
                          sym_sec = hh->root.u.def.section;
2019
                          sym_value = hh->root.u.def.value;
2020
                          if (sym_sec->output_section != NULL)
2021
                            destination = (sym_value + irela->r_addend
2022
                                           + sym_sec->output_offset
2023
                                           + sym_sec->output_section->vma);
2024
                        }
2025
                      else if (hh->root.type == bfd_link_hash_undefweak)
2026
                        {
2027
                          if (! info->shared)
2028
                            continue;
2029
                        }
2030
                      else if (hh->root.type == bfd_link_hash_undefined)
2031
                        {
2032
                          if (! (info->unresolved_syms_in_objects == RM_IGNORE
2033
                                 && (ELF_ST_VISIBILITY (hh->other)
2034
                                     == STV_DEFAULT)))
2035
                            continue;
2036
                        }
2037
                      else
2038
                        {
2039
                          bfd_set_error (bfd_error_bad_value);
2040
 
2041
                        error_ret_free_internal:
2042
                          if (elf_section_data (section)->relocs == NULL)
2043
                            free (internal_relocs);
2044
                          goto error_ret_free_local;
2045
                        }
2046
                    }
2047
 
2048
                  if (! open8_stub_is_required_for_16_bit_reloc
2049
                      (destination - htab->vector_base))
2050
                    {
2051
                      if (!is_prealloc_run)
2052
                        /* We are having a reloc that does't need a stub.  */
2053
                        continue;
2054
 
2055
                      /* We don't right now know if a stub will be needed.
2056
                         Let's rather be on the safe side.  */
2057
                    }
2058
 
2059
                  /* Get the name of this stub.  */
2060
                  stub_name = open8_stub_name (sym_sec, sym_value, irela);
2061
 
2062
                  if (!stub_name)
2063
                    goto error_ret_free_internal;
2064
 
2065
 
2066
                  hsh = open8_stub_hash_lookup (&htab->bstab,
2067
                                                stub_name,
2068
                                                FALSE, FALSE);
2069
                  if (hsh != NULL)
2070
                    {
2071
                      /* The proper stub has already been created.  Mark it
2072
                         to be used and write the possibly changed destination
2073
                         value.  */
2074
                      hsh->is_actually_needed = TRUE;
2075
                      hsh->target_value = destination;
2076
                      free (stub_name);
2077
                      continue;
2078
                    }
2079
 
2080
                  hsh = open8_add_stub (stub_name, htab);
2081
                  if (hsh == NULL)
2082
                    {
2083
                      free (stub_name);
2084
                      goto error_ret_free_internal;
2085
                    }
2086
 
2087
                  hsh->is_actually_needed = TRUE;
2088
                  hsh->target_value = destination;
2089
 
2090
                  if (debug_stubs)
2091
                    printf ("Adding stub with destination 0x%x to the"
2092
                            " hash table.\n", (unsigned int) destination);
2093
                  if (debug_stubs)
2094
                    printf ("(Pre-Alloc run: %i)\n", is_prealloc_run);
2095
 
2096
                  stub_changed = TRUE;
2097
                }
2098
 
2099
              /* We're done with the internal relocs, free them.  */
2100
              if (elf_section_data (section)->relocs == NULL)
2101
                free (internal_relocs);
2102
            }
2103
        }
2104
 
2105
      /* Re-Calculate the number of needed stubs.  */
2106
      htab->stub_sec->size = 0;
2107
      bfd_hash_traverse (&htab->bstab, open8_size_one_stub, htab);
2108
 
2109
      if (!stub_changed)
2110
        break;
2111
 
2112
      stub_changed = FALSE;
2113
    }
2114
 
2115
  free (htab->all_local_syms);
2116
  return TRUE;
2117
 
2118
 error_ret_free_local:
2119
  free (htab->all_local_syms);
2120
  return FALSE;
2121
}
2122
 
2123
 
2124
/* Build all the stubs associated with the current output file.  The
2125
   stubs are kept in a hash table attached to the main linker hash
2126
   table.  We also set up the `.plt' entries for statically linked PIC
2127
   functions here.  This function is called via hppaelf_finish in the
2128
   linker.  */
2129
 
2130
bfd_boolean
2131
elf32_open8_build_stubs (struct bfd_link_info *info)
2132
{
2133
  asection *stub_sec;
2134
  struct bfd_hash_table *table;
2135
  struct elf32_open8_link_hash_table *htab;
2136
  bfd_size_type total_size = 0;
2137
 
2138
  htab = open8_link_hash_table (info);
2139
  if (htab == NULL)
2140
    return FALSE;
2141
 
2142
  /* In case that there were several stub sections: */
2143
  for (stub_sec = htab->stub_bfd->sections;
2144
       stub_sec != NULL;
2145
       stub_sec = stub_sec->next)
2146
    {
2147
      bfd_size_type size;
2148
 
2149
      /* Allocate memory to hold the linker stubs.  */
2150
      size = stub_sec->size;
2151
      total_size += size;
2152
 
2153
      stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
2154
      if (stub_sec->contents == NULL && size != 0)
2155
        return FALSE;
2156
      stub_sec->size = 0;
2157
    }
2158
 
2159
  /* Allocate memory for the address mapping table.  */
2160
  htab->amt_entry_cnt = 0;
2161
  htab->amt_max_entry_cnt = total_size / 4;
2162
  htab->amt_stub_offsets = bfd_malloc (sizeof (bfd_vma)
2163
                                       * htab->amt_max_entry_cnt);
2164
  htab->amt_destination_addr = bfd_malloc (sizeof (bfd_vma)
2165
                                           * htab->amt_max_entry_cnt);
2166
 
2167
  if (debug_stubs)
2168
    printf ("Allocating %i entries in the AMT\n", htab->amt_max_entry_cnt);
2169
 
2170
  /* Build the stubs as directed by the stub hash table.  */
2171
  table = &htab->bstab;
2172
  bfd_hash_traverse (table, open8_build_one_stub, info);
2173
 
2174
  if (debug_stubs)
2175
    printf ("Final Stub section Size: %i\n", (int) htab->stub_sec->size);
2176
 
2177
  return TRUE;
2178
}
2179
 
2180
#define ELF_ARCH                bfd_arch_open8
2181
#define ELF_TARGET_ID           OPEN8_ELF_DATA
2182
#define ELF_MACHINE_CODE        EM_OPEN8
2183
#define ELF_MAXPAGESIZE         1
2184
 
2185
#define TARGET_LITTLE_SYM       bfd_elf32_open8_vec
2186
#define TARGET_LITTLE_NAME      "elf32-open8"
2187
 
2188
#define bfd_elf32_bfd_link_hash_table_create elf32_open8_link_hash_table_create
2189
#define bfd_elf32_bfd_link_hash_table_free   elf32_open8_link_hash_table_free
2190
 
2191
#define elf_info_to_howto                    open8_info_to_howto_rela
2192
#define elf_info_to_howto_rel                NULL
2193
#define elf_backend_relocate_section         elf32_open8_relocate_section
2194
#define elf_backend_can_gc_sections          1
2195
#define elf_backend_rela_normal              1
2196
#define elf_backend_final_write_processing      \
2197
  bfd_elf_open8_final_write_processing
2198
#define elf_backend_object_p            elf32_open8_object_p
2199
 
2200
#define bfd_elf32_bfd_relax_section elf32_open8_relax_section
2201
#define bfd_elf32_bfd_get_relocated_section_contents    \
2202
  elf32_open8_get_relocated_section_contents
2203
 
2204
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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