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 166

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 166 khays
  /* Absolute addr of the reloc in the final executable.  */
482 14 khays
  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 166 khays
      srel = rel->r_addend - (reloc_addr + 1);
490 14 khays
 
491 166 khays
      if ((srel > 127) || (srel < -128))
492 14 khays
        return bfd_reloc_overflow;
493
      x = bfd_get_16 (input_bfd, contents);
494
      x = (x & 0xff00) | (srel & 0xff);
495
      bfd_put_16 (input_bfd, x, contents);
496
      break;
497
 
498
    case R_OPEN8_CALL:
499
      contents += rel->r_offset;
500
      srel = (bfd_signed_vma) relocation + rel->r_addend;
501
      bfd_put_16 (input_bfd, srel, contents);
502
      break;
503
 
504
    case R_OPEN8_LO8_LDI:
505
      contents += rel->r_offset;
506
      srel = (bfd_signed_vma) relocation + rel->r_addend;
507
      x = bfd_get_16 (input_bfd, contents);
508
      x = (x & 0xff00) | (srel & 0x0ff);
509
      bfd_put_16 (input_bfd, x, contents);
510
      break;
511
 
512
    case R_OPEN8_HI8_LDI:
513
      contents += rel->r_offset;
514
      srel = (bfd_signed_vma) relocation + rel->r_addend;
515
      x = bfd_get_16 (input_bfd, contents);
516
      x = (x & 0xff00) | ((srel >> 4) & 0x0ff);
517
      bfd_put_16 (input_bfd, x, contents);
518
      break;
519
 
520
    case R_OPEN8_LO8_LDI_NEG:
521
      contents += rel->r_offset;
522
      srel = (bfd_signed_vma) relocation + rel->r_addend;
523
      srel = -srel;
524
      x = bfd_get_16 (input_bfd, contents);
525
      x = (x & 0xff00) | (srel & 0x0ff);
526
      bfd_put_16 (input_bfd, x, contents);
527
      break;
528
 
529
    case R_OPEN8_HI8_LDI_NEG:
530
      contents += rel->r_offset;
531
      srel = (bfd_signed_vma) relocation + rel->r_addend;
532
      srel = -srel;
533
      x = bfd_get_16 (input_bfd, contents);
534
      x = (x & 0xff00) | ((srel >> 4) & 0x0ff);
535
      bfd_put_16 (input_bfd, x, contents);
536
      break;
537
 
538
    default:
539
      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
540
                                    contents, rel->r_offset,
541
                                    relocation, rel->r_addend);
542
    }
543
 
544
  return r;
545
}
546
 
547
/* Relocate an OPEN8 ELF section.  */
548
 
549
static bfd_boolean
550
elf32_open8_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
551
                              struct bfd_link_info *info,
552
                              bfd *input_bfd,
553
                              asection *input_section,
554
                              bfd_byte *contents,
555
                              Elf_Internal_Rela *relocs,
556
                              Elf_Internal_Sym *local_syms,
557
                              asection **local_sections)
558
{
559
  Elf_Internal_Shdr *           symtab_hdr;
560
  struct elf_link_hash_entry ** sym_hashes;
561
  Elf_Internal_Rela *           rel;
562
  Elf_Internal_Rela *           relend;
563
  struct elf32_open8_link_hash_table * htab = open8_link_hash_table (info);
564
 
565
  if (htab == NULL)
566
    return FALSE;
567
 
568
  symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
569
  sym_hashes = elf_sym_hashes (input_bfd);
570
  relend     = relocs + input_section->reloc_count;
571
 
572
  for (rel = relocs; rel < relend; rel ++)
573
    {
574
      reloc_howto_type *           howto;
575
      unsigned long                r_symndx;
576
      Elf_Internal_Sym *           sym;
577
      asection *                   sec;
578
      struct elf_link_hash_entry * h;
579
      bfd_vma                      relocation;
580
      bfd_reloc_status_type        r;
581
      const char *                 name;
582
      int                          r_type;
583
 
584
      r_type = ELF32_R_TYPE (rel->r_info);
585
      r_symndx = ELF32_R_SYM (rel->r_info);
586
      howto  = elf_open8_howto_table + r_type;
587
      h      = NULL;
588
      sym    = NULL;
589
      sec    = NULL;
590
 
591
      if (r_symndx < symtab_hdr->sh_info)
592
        {
593
          sym = local_syms + r_symndx;
594
          sec = local_sections [r_symndx];
595
          relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
596
 
597
          name = bfd_elf_string_from_elf_section
598
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
599
          name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
600
        }
601
      else
602
        {
603
          bfd_boolean unresolved_reloc, warned;
604
 
605
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
606
                                   r_symndx, symtab_hdr, sym_hashes,
607
                                   h, sec, relocation,
608
                                   unresolved_reloc, warned);
609
 
610
          name = h->root.root.string;
611
        }
612
 
613
      if (sec != NULL && elf_discarded_section (sec))
614
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
615
                                         rel, relend, howto, contents);
616
 
617
      if (info->relocatable)
618
        continue;
619
 
620
      r = open8_final_link_relocate (howto, input_bfd, input_section,
621
                                     contents, rel, relocation);
622
 
623
      if (r != bfd_reloc_ok)
624
        {
625
          const char * msg = (const char *) NULL;
626
 
627
          switch (r)
628
            {
629
            case bfd_reloc_overflow:
630
              r = info->callbacks->reloc_overflow
631
                (info, (h ? &h->root : NULL),
632
                 name, howto->name, (bfd_vma) 0,
633
                 input_bfd, input_section, rel->r_offset);
634
              break;
635
 
636
            case bfd_reloc_undefined:
637
              r = info->callbacks->undefined_symbol
638
                (info, name, input_bfd, input_section, rel->r_offset, TRUE);
639
              break;
640
 
641
            case bfd_reloc_outofrange:
642
              msg = _("internal error: out of range error");
643
              break;
644
 
645
            case bfd_reloc_notsupported:
646
              msg = _("internal error: unsupported relocation error");
647
              break;
648
 
649
            case bfd_reloc_dangerous:
650
              msg = _("internal error: dangerous relocation");
651
              break;
652
 
653
            default:
654
              msg = _("internal error: unknown error");
655
              break;
656
            }
657
 
658
          if (msg)
659
            r = info->callbacks->warning
660
              (info, msg, name, input_bfd, input_section, rel->r_offset);
661
 
662
          if (! r)
663
            return FALSE;
664
        }
665
    }
666
 
667
  return TRUE;
668
}
669
 
670
/* The final processing done just before writing out a OPEN8 ELF object
671
   file.  This gets the OPEN8 architecture right based on the machine
672
   number.  */
673
 
674
static void
675
bfd_elf_open8_final_write_processing (bfd *abfd,
676
                                      bfd_boolean linker ATTRIBUTE_UNUSED)
677
{
678
  unsigned long val;
679
 
680
  switch (bfd_get_mach (abfd))
681
    {
682
    default:
683
    case bfd_mach_open8_1:
684
      val = E_OPEN8_MACH_OPEN8_1;
685
      break;
686
    }
687
 
688
  elf_elfheader (abfd)->e_machine = EM_OPEN8;
689
  elf_elfheader (abfd)->e_flags &= ~ EF_OPEN8_MACH;
690
  elf_elfheader (abfd)->e_flags |= val;
691
  elf_elfheader (abfd)->e_flags |= EF_OPEN8_LINKRELAX_PREPARED;
692
}
693
 
694
/* Set the right machine number.  */
695
 
696
static bfd_boolean
697
elf32_open8_object_p (bfd *abfd)
698
{
699
  unsigned int e_set = bfd_mach_open8_1;
700
 
701
  if (elf_elfheader (abfd)->e_machine == EM_OPEN8)
702
    {
703
      int e_mach = elf_elfheader (abfd)->e_flags & EF_OPEN8_MACH;
704
 
705
      switch (e_mach)
706
        {
707
        default:
708
        case E_OPEN8_MACH_OPEN8_1:
709
          e_set = bfd_mach_open8_1;
710
          break;
711
 
712
        }
713
    }
714
  return bfd_default_set_arch_mach (abfd, bfd_arch_open8,
715
                                    e_set);
716
}
717
 
718
 
719
/* Delete some bytes from a section while changing the size of an instruction.
720
   The parameter "addr" denotes the section-relative offset pointing just
721
   behind the shrinked instruction. "addr+count" point at the first
722
   byte just behind the original unshrinked instruction.  */
723
 
724
static bfd_boolean
725
elf32_open8_relax_delete_bytes (bfd *abfd,
726
                                asection *sec,
727
                                bfd_vma addr,
728
                                int count)
729
{
730
  Elf_Internal_Shdr *symtab_hdr;
731
  unsigned int sec_shndx;
732
  bfd_byte *contents;
733
  Elf_Internal_Rela *irel, *irelend;
734
  Elf_Internal_Sym *isym;
735
  Elf_Internal_Sym *isymbuf = NULL;
736
  bfd_vma toaddr;
737
  struct elf_link_hash_entry **sym_hashes;
738
  struct elf_link_hash_entry **end_hashes;
739
  unsigned int symcount;
740
 
741
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
742
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
743
  contents = elf_section_data (sec)->this_hdr.contents;
744
 
745
  toaddr = sec->size;
746
 
747
  irel = elf_section_data (sec)->relocs;
748
  irelend = irel + sec->reloc_count;
749
 
750
  /* Actually delete the bytes.  */
751
  if (toaddr - addr - count > 0)
752
    memmove (contents + addr, contents + addr + count,
753
             (size_t) (toaddr - addr - count));
754
  sec->size -= count;
755
 
756
  /* Adjust all the reloc addresses.  */
757
  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
758
    {
759
      bfd_vma old_reloc_address;
760
 
761
      old_reloc_address = (sec->output_section->vma
762
                           + sec->output_offset + irel->r_offset);
763
 
764
      /* Get the new reloc address.  */
765
      if ((irel->r_offset > addr
766
           && irel->r_offset < toaddr))
767
        {
768
          if (debug_relax)
769
            printf ("Relocation at address 0x%x needs to be moved.\n"
770
                    "Old section offset: 0x%x, New section offset: 0x%x \n",
771
                    (unsigned int) old_reloc_address,
772
                    (unsigned int) irel->r_offset,
773
                    (unsigned int) ((irel->r_offset) - count));
774
 
775
          irel->r_offset -= count;
776
        }
777
 
778
    }
779
 
780
  /* The reloc's own addresses are now ok.  However, we need to readjust
781
     the reloc's addend, i.e., the reloc's value if two conditions are met:
782
     1.) the reloc is relative to a symbol in this section that
783
     is located in front of the shrinked instruction
784
     2.) symbol plus addend end up behind the shrinked instruction.
785
 
786
     The most common case where this happens are relocs relative to
787
     the section-start symbol.
788
 
789
     This step needs to be done for all of the sections of the bfd.  */
790
 
791
  {
792
    struct bfd_section *isec;
793
 
794
    for (isec = abfd->sections; isec; isec = isec->next)
795
      {
796
        bfd_vma symval;
797
        bfd_vma shrinked_insn_address;
798
 
799
        shrinked_insn_address = (sec->output_section->vma
800
                                 + sec->output_offset + addr - count);
801
 
802
        irelend = elf_section_data (isec)->relocs + isec->reloc_count;
803
        for (irel = elf_section_data (isec)->relocs;
804
             irel < irelend;
805
             irel++)
806
          {
807
            /* Read this BFD's local symbols if we haven't done
808
               so already.  */
809
            if (isymbuf == NULL && symtab_hdr->sh_info != 0)
810
              {
811
                isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
812
                if (isymbuf == NULL)
813
                  isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
814
                                                  symtab_hdr->sh_info, 0,
815
                                                  NULL, NULL, NULL);
816
                if (isymbuf == NULL)
817
                  return FALSE;
818
              }
819
 
820
            /* Get the value of the symbol referred to by the reloc.  */
821
            if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
822
              {
823
                /* A local symbol.  */
824
                asection *sym_sec;
825
 
826
                isym = isymbuf + ELF32_R_SYM (irel->r_info);
827
                sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
828
                symval = isym->st_value;
829
                /* If the reloc is absolute, it will not have
830
                   a symbol or section associated with it.  */
831
                if (sym_sec == sec)
832
                  {
833
                    symval += sym_sec->output_section->vma
834
                      + sym_sec->output_offset;
835
 
836
                    if (debug_relax)
837
                      printf ("Checking if the relocation's "
838
                              "addend needs corrections.\n"
839
                              "Address of anchor symbol: 0x%x \n"
840
                              "Address of relocation target: 0x%x \n"
841
                              "Address of relaxed insn: 0x%x \n",
842
                              (unsigned int) symval,
843
                              (unsigned int) (symval + irel->r_addend),
844
                              (unsigned int) shrinked_insn_address);
845
 
846
                    if (symval <= shrinked_insn_address
847
                        && (symval + irel->r_addend) > shrinked_insn_address)
848
                      {
849
                        irel->r_addend -= count;
850
 
851
                        if (debug_relax)
852
                          printf ("Relocation's addend needed to be fixed \n");
853
                      }
854
                  }
855
                /* else, reference symbol is absolute.
856
                   No adjustment needed.  */
857
              }
858
            /* else, reference symbol is extern.  No need for adjusting
859
               the addend.  */
860
          }
861
      }
862
  }
863
 
864
  /* Adjust the local symbols defined in this section.  */
865
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
866
  /* Fix PR 9841, there may be no local symbols.  */
867
  if (isym != NULL)
868
    {
869
      Elf_Internal_Sym *isymend;
870
 
871
      isymend = isym + symtab_hdr->sh_info;
872
      for (; isym < isymend; isym++)
873
        {
874
          if (isym->st_shndx == sec_shndx
875
              && isym->st_value > addr
876
              && isym->st_value < toaddr)
877
            isym->st_value -= count;
878
        }
879
    }
880
 
881
  /* Now adjust the global symbols defined in this section.  */
882
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
883
              - symtab_hdr->sh_info);
884
  sym_hashes = elf_sym_hashes (abfd);
885
  end_hashes = sym_hashes + symcount;
886
  for (; sym_hashes < end_hashes; sym_hashes++)
887
    {
888
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
889
      if ((sym_hash->root.type == bfd_link_hash_defined
890
           || sym_hash->root.type == bfd_link_hash_defweak)
891
          && sym_hash->root.u.def.section == sec
892
          && sym_hash->root.u.def.value > addr
893
          && sym_hash->root.u.def.value < toaddr)
894
        {
895
          sym_hash->root.u.def.value -= count;
896
        }
897
    }
898
 
899
  return TRUE;
900
}
901
 
902
/* This function handles relaxing for the open8.
903
   Many important relaxing opportunities within functions are already
904
   realized by the compiler itself.
905
   Here we try to replace branch followed by jump with a reverse branch.
906
   As well we now optimize sequences of
907
   - call/rcall function
908
   - ret
909
   to yield
910
   - jmp/ function
911
   - ret
912
   . In case that within a sequence
913
   - jmp/rjmp label
914
   - ret
915
   the ret could no longer be reached it is optimized away.  In order
916
   to check if the ret is no longer needed, it is checked that the ret's address
917
   is not the target of a branch or jump within the same section, it is checked
918
   that there is no skip instruction before the jmp/rjmp and that there
919
   is no local or global label placed at the address of the ret.
920
 
921
   We refrain from relaxing within sections ".vectors" and
922
   ".jumptables" in order to maintain the position of the instructions.
923
   There, however, we substitute jmp/call by a sequence rjmp,nop/rcall,nop
924
   if possible. (In the future, one could possibly use the space of the nop
925
   for the first instruction of the irq service function.)
926
 
927
*/
928
 
929
static bfd_boolean
930
elf32_open8_relax_section (bfd *abfd,
931
                           asection *sec,
932
                           struct bfd_link_info *link_info,
933
                           bfd_boolean *again)
934
{
935
  Elf_Internal_Shdr *symtab_hdr;
936
  Elf_Internal_Rela *internal_relocs;
937
  Elf_Internal_Rela *irel, *irelend;
938
  bfd_byte *contents = NULL;
939
  Elf_Internal_Sym *isymbuf = NULL;
940
  struct elf32_open8_link_hash_table *htab;
941
 
942
  if (link_info->relocatable)
943
    (*link_info->callbacks->einfo)
944
      (_("%P%F: --relax and -r may not be used together\n"));
945
 
946
/* TODO - MAJOR REWORK NEEDED HERE!!!
947
   This code is AVR relaxation, need open8 version.  */
948
  return FALSE;
949
 
950
  htab = open8_link_hash_table (link_info);
951
  if (htab == NULL)
952
    return FALSE;
953
 
954
  /* Assume nothing changes.  */
955
  *again = FALSE;
956
 
957
  if ((!htab->no_stubs) && (sec == htab->stub_sec))
958
    {
959
      /* We are just relaxing the stub section.
960
         Let's calculate the size needed again.  */
961
      bfd_size_type last_estimated_stub_section_size = htab->stub_sec->size;
962
 
963
      if (debug_relax)
964
        printf ("Relaxing the stub section.  Size prior to this pass: %i\n",
965
                (int) last_estimated_stub_section_size);
966
 
967
      elf32_open8_size_stubs (htab->stub_sec->output_section->owner,
968
                              link_info, FALSE);
969
 
970
      /* Check if the number of trampolines changed.  */
971
      if (last_estimated_stub_section_size != htab->stub_sec->size)
972
        *again = TRUE;
973
 
974
      if (debug_relax)
975
        printf ("Size of stub section after this pass: %i\n",
976
                (int) htab->stub_sec->size);
977
 
978
      return TRUE;
979
    }
980
 
981
  /* We don't have to do anything for a relocatable link, if
982
     this section does not have relocs, or if this is not a
983
     code section.  */
984
  if (link_info->relocatable
985
      || (sec->flags & SEC_RELOC) == 0
986
      || sec->reloc_count == 0
987
      || (sec->flags & SEC_CODE) == 0)
988
    return TRUE;
989
 
990
  /* Check if the object file to relax uses internal symbols so that we
991
     could fix up the relocations.  */
992
  if (!(elf_elfheader (abfd)->e_flags & EF_OPEN8_LINKRELAX_PREPARED))
993
    return TRUE;
994
 
995
  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
996
 
997
  /* Get a copy of the native relocations.  */
998
  internal_relocs = (_bfd_elf_link_read_relocs
999
                     (abfd, sec, NULL, NULL, link_info->keep_memory));
1000
  if (internal_relocs == NULL)
1001
    goto error_return;
1002
 
1003
  /* Walk through the relocs looking for relaxing opportunities.  */
1004
  irelend = internal_relocs + sec->reloc_count;
1005
  for (irel = internal_relocs; irel < irelend; irel++)
1006
    {
1007
      bfd_vma symval;
1008
 
1009
      if (   ELF32_R_TYPE (irel->r_info) != R_OPEN8_PCREL
1010
             && ELF32_R_TYPE (irel->r_info) != R_OPEN8_CALL)
1011
        continue;
1012
 
1013
      /* Get the section contents if we haven't done so already.  */
1014
      if (contents == NULL)
1015
        {
1016
          /* Get cached copy if it exists.  */
1017
          if (elf_section_data (sec)->this_hdr.contents != NULL)
1018
            contents = elf_section_data (sec)->this_hdr.contents;
1019
          else
1020
            {
1021
              /* Go get them off disk.  */
1022
              if (! bfd_malloc_and_get_section (abfd, sec, &contents))
1023
                goto error_return;
1024
            }
1025
        }
1026
 
1027
      /* Read this BFD's local symbols if we haven't done so already.  */
1028
      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1029
        {
1030
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1031
          if (isymbuf == NULL)
1032
            isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
1033
                                            symtab_hdr->sh_info, 0,
1034
                                            NULL, NULL, NULL);
1035
          if (isymbuf == NULL)
1036
            goto error_return;
1037
        }
1038
 
1039
 
1040
      /* Get the value of the symbol referred to by the reloc.  */
1041
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1042
        {
1043
          /* A local symbol.  */
1044
          Elf_Internal_Sym *isym;
1045
          asection *sym_sec;
1046
 
1047
          isym = isymbuf + ELF32_R_SYM (irel->r_info);
1048
          sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1049
          symval = isym->st_value;
1050
          /* If the reloc is absolute, it will not have
1051
             a symbol or section associated with it.  */
1052
          if (sym_sec)
1053
            symval += sym_sec->output_section->vma
1054
              + sym_sec->output_offset;
1055
        }
1056
      else
1057
        {
1058
          unsigned long indx;
1059
          struct elf_link_hash_entry *h;
1060
 
1061
          /* An external symbol.  */
1062
          indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1063
          h = elf_sym_hashes (abfd)[indx];
1064
          BFD_ASSERT (h != NULL);
1065
          if (h->root.type != bfd_link_hash_defined
1066
              && h->root.type != bfd_link_hash_defweak)
1067
            /* This appears to be a reference to an undefined
1068
               symbol.  Just ignore it--it will be caught by the
1069
               regular reloc processing.  */
1070
            continue;
1071
 
1072
          symval = (h->root.u.def.value
1073
                    + h->root.u.def.section->output_section->vma
1074
                    + h->root.u.def.section->output_offset);
1075
        }
1076
 
1077
      /* For simplicity of coding, we are going to modify the section
1078
         contents, the section relocs, and the BFD symbol table.  We
1079
         must tell the rest of the code not to free up this
1080
         information.  It would be possible to instead create a table
1081
         of changes which have to be made, as is done in coff-mips.c;
1082
         that would be more work, but would require less memory when
1083
         the linker is run.  */
1084
      switch (ELF32_R_TYPE (irel->r_info))
1085
        {
1086
 
1087
        default:
1088
          {
1089
            unsigned char code_msb;
1090
            unsigned char code_lsb;
1091
            bfd_vma dot;
1092
 
1093
            code_msb = bfd_get_8 (abfd, contents + irel->r_offset + 1);
1094
            code_lsb = bfd_get_8 (abfd, contents + irel->r_offset + 0);
1095
 
1096
            /* Get the address of this instruction.  */
1097
            dot = (sec->output_section->vma
1098
                   + sec->output_offset + irel->r_offset);
1099
 
1100
            /* Here we look for rcall/ret or call/ret sequences that could be
1101
               safely replaced by rjmp/ret or jmp/ret.  */
1102
            if (((code_msb & 0xf0) == 0xd0)
1103
                && open8_replace_call_ret_sequences)
1104
              {
1105
                /* This insn is a rcall.  */
1106
                unsigned char next_insn_msb = 0;
1107
                unsigned char next_insn_lsb = 0;
1108
 
1109
                if (irel->r_offset + 3 < sec->size)
1110
                  {
1111
                    next_insn_msb =
1112
                      bfd_get_8 (abfd, contents + irel->r_offset + 3);
1113
                    next_insn_lsb =
1114
                      bfd_get_8 (abfd, contents + irel->r_offset + 2);
1115
                  }
1116
 
1117
                if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
1118
                  {
1119
                    /* The next insn is a ret.  We now convert the rcall insn
1120
                       into a rjmp instruction.  */
1121
                    code_msb &= 0xef;
1122
                    bfd_put_8 (abfd, code_msb, contents + irel->r_offset + 1);
1123
                    if (debug_relax)
1124
                      printf ("converted rcall/ret sequence at address 0x%x"
1125
                              " into rjmp/ret sequence.  Section is %s\n\n",
1126
                              (int) dot, sec->name);
1127
                    *again = TRUE;
1128
                    break;
1129
                  }
1130
              }
1131
            else if ((0x94 == (code_msb & 0xfe))
1132
                     && (0x0e == (code_lsb & 0x0e))
1133
                     && open8_replace_call_ret_sequences)
1134
              {
1135
                /* This insn is a call.  */
1136
                unsigned char next_insn_msb = 0;
1137
                unsigned char next_insn_lsb = 0;
1138
 
1139
                if (irel->r_offset + 5 < sec->size)
1140
                  {
1141
                    next_insn_msb =
1142
                      bfd_get_8 (abfd, contents + irel->r_offset + 5);
1143
                    next_insn_lsb =
1144
                      bfd_get_8 (abfd, contents + irel->r_offset + 4);
1145
                  }
1146
 
1147
                if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
1148
                  {
1149
                    /* The next insn is a ret.  We now convert the call insn
1150
                       into a jmp instruction.  */
1151
 
1152
                    code_lsb &= 0xfd;
1153
                    bfd_put_8 (abfd, code_lsb, contents + irel->r_offset);
1154
                    if (debug_relax)
1155
                      printf ("converted call/ret sequence at address 0x%x"
1156
                              " into jmp/ret sequence.  Section is %s\n\n",
1157
                              (int) dot, sec->name);
1158
                    *again = TRUE;
1159
                    break;
1160
                  }
1161
              }
1162
            else if ((0xc0 == (code_msb & 0xf0))
1163
                     || ((0x94 == (code_msb & 0xfe))
1164
                         && (0x0c == (code_lsb & 0x0e))))
1165
              {
1166
                /* This insn is a rjmp or a jmp.  */
1167
                unsigned char next_insn_msb = 0;
1168
                unsigned char next_insn_lsb = 0;
1169
                int insn_size;
1170
 
1171
                if (0xc0 == (code_msb & 0xf0))
1172
                  insn_size = 2;
1173
                else
1174
                  insn_size = 4;
1175
 
1176
                if (irel->r_offset + insn_size + 1 < sec->size)
1177
                  {
1178
                    next_insn_msb =
1179
                      bfd_get_8 (abfd, contents + irel->r_offset
1180
                                 + insn_size + 1);
1181
                    next_insn_lsb =
1182
                      bfd_get_8 (abfd, contents + irel->r_offset
1183
                                 + insn_size);
1184
                  }
1185
 
1186
                if ((0x95 == next_insn_msb) && (0x08 == next_insn_lsb))
1187
                  {
1188
                    /* The next insn is a ret.  We possibly could delete
1189
                       this ret.  First we need to check for preceeding
1190
                       sbis/sbic/sbrs or cpse "skip" instructions.  */
1191
 
1192
                    int there_is_preceeding_non_skip_insn = 1;
1193
                    bfd_vma address_of_ret;
1194
 
1195
                    address_of_ret = dot + insn_size;
1196
 
1197
                    if (debug_relax && (insn_size == 2))
1198
                      printf ("found rjmp / ret sequence at address 0x%x\n",
1199
                              (int) dot);
1200
                    if (debug_relax && (insn_size == 4))
1201
                      printf ("found jmp / ret sequence at address 0x%x\n",
1202
                              (int) dot);
1203
 
1204
                    /* We have to make sure that there is a preceeding insn.  */
1205
                    if (irel->r_offset >= 2)
1206
                      {
1207
                        unsigned char preceeding_msb;
1208
                        unsigned char preceeding_lsb;
1209
                        preceeding_msb =
1210
                          bfd_get_8 (abfd, contents + irel->r_offset - 1);
1211
                        preceeding_lsb =
1212
                          bfd_get_8 (abfd, contents + irel->r_offset - 2);
1213
 
1214
                        /* sbic.  */
1215
                        if (0x99 == preceeding_msb)
1216
                          there_is_preceeding_non_skip_insn = 0;
1217
 
1218
                        /* sbis.  */
1219
                        if (0x9b == preceeding_msb)
1220
                          there_is_preceeding_non_skip_insn = 0;
1221
 
1222
                        /* sbrc.  */
1223
                        if ((0xfc == (preceeding_msb & 0xfe)
1224
                             && (0x00 == (preceeding_lsb & 0x08))))
1225
                          there_is_preceeding_non_skip_insn = 0;
1226
 
1227
                        /* sbrs.  */
1228
                        if ((0xfe == (preceeding_msb & 0xfe)
1229
                             && (0x00 == (preceeding_lsb & 0x08))))
1230
                          there_is_preceeding_non_skip_insn = 0;
1231
 
1232
                        /* cpse.  */
1233
                        if (0x10 == (preceeding_msb & 0xfc))
1234
                          there_is_preceeding_non_skip_insn = 0;
1235
 
1236
                        if (there_is_preceeding_non_skip_insn == 0)
1237
                          if (debug_relax)
1238
                            printf ("preceeding skip insn prevents deletion of"
1239
                                    " ret insn at addr 0x%x in section %s\n",
1240
                                    (int) dot + 2, sec->name);
1241
                      }
1242
                    else
1243
                      {
1244
                        /* There is no previous instruction.  */
1245
                        there_is_preceeding_non_skip_insn = 0;
1246
                      }
1247
 
1248
                    if (there_is_preceeding_non_skip_insn)
1249
                      {
1250
                        /* We now only have to make sure that there is no
1251
                           local label defined at the address of the ret
1252
                           instruction and that there is no local relocation
1253
                           in this section pointing to the ret.  */
1254
 
1255
                        int deleting_ret_is_safe = 1;
1256
                        unsigned int section_offset_of_ret_insn =
1257
                          irel->r_offset + insn_size;
1258
                        Elf_Internal_Sym *isym, *isymend;
1259
                        unsigned int sec_shndx;
1260
 
1261
                        sec_shndx =
1262
                          _bfd_elf_section_from_bfd_section (abfd, sec);
1263
 
1264
                        /* Check for local symbols.  */
1265
                        isym = (Elf_Internal_Sym *) symtab_hdr->contents;
1266
                        isymend = isym + symtab_hdr->sh_info;
1267
                        /* PR 6019: There may not be any local symbols.  */
1268
                        for (; isym != NULL && isym < isymend; isym++)
1269
                          {
1270
                            if (isym->st_value == section_offset_of_ret_insn
1271
                                && isym->st_shndx == sec_shndx)
1272
                              {
1273
                                deleting_ret_is_safe = 0;
1274
                                if (debug_relax)
1275
                                  printf ("local label prevents deletion of"
1276
                                          "ret insn at address 0x%x\n",
1277
                                          (int) dot + insn_size);
1278
                              }
1279
                          }
1280
 
1281
                        /* Now check for global symbols.  */
1282
                        {
1283
                          int symcount;
1284
                          struct elf_link_hash_entry **sym_hashes;
1285
                          struct elf_link_hash_entry **end_hashes;
1286
 
1287
                          symcount = (symtab_hdr->sh_size
1288
                                      / sizeof (Elf32_External_Sym)
1289
                                      - symtab_hdr->sh_info);
1290
                          sym_hashes = elf_sym_hashes (abfd);
1291
                          end_hashes = sym_hashes + symcount;
1292
                          for (; sym_hashes < end_hashes; sym_hashes++)
1293
                            {
1294
                              struct elf_link_hash_entry *sym_hash =
1295
                                *sym_hashes;
1296
                              if ((sym_hash->root.type == bfd_link_hash_defined
1297
                                   || sym_hash->root.type ==
1298
                                   bfd_link_hash_defweak)
1299
                                  && sym_hash->root.u.def.section == sec
1300
                                  && (sym_hash->root.u.def.value
1301
                                      == section_offset_of_ret_insn))
1302
                                {
1303
                                  deleting_ret_is_safe = 0;
1304
                                  if (debug_relax)
1305
                                    printf ("global label prevents deletion of "
1306
                                            "ret insn at address 0x%x\n",
1307
                                            (int) dot + insn_size);
1308
                                }
1309
                            }
1310
                        }
1311
                        /* Now we check for relocations pointing to ret.  */
1312
                        {
1313
                          Elf_Internal_Rela *rel;
1314
                          Elf_Internal_Rela *relend;
1315
 
1316
                          relend = elf_section_data (sec)->relocs
1317
                            + sec->reloc_count;
1318
 
1319
                          for (rel = elf_section_data (sec)->relocs;
1320
                               rel < relend; rel++)
1321
                            {
1322
                              bfd_vma reloc_target = 0;
1323
 
1324
                              /* Read this BFD's local symbols if we haven't
1325
                                 done so already.  */
1326
                              if (isymbuf == NULL && symtab_hdr->sh_info != 0)
1327
                                {
1328
                                  isymbuf = (Elf_Internal_Sym *)
1329
                                    symtab_hdr->contents;
1330
                                  if (isymbuf == NULL)
1331
                                    isymbuf = bfd_elf_get_elf_syms
1332
                                      (abfd,
1333
                                       symtab_hdr,
1334
                                       symtab_hdr->sh_info, 0,
1335
                                       NULL, NULL, NULL);
1336
                                  if (isymbuf == NULL)
1337
                                    break;
1338
                                }
1339
 
1340
                              /* Get the value of the symbol referred to
1341
                                 by the reloc.  */
1342
                              if (ELF32_R_SYM (rel->r_info)
1343
                                  < symtab_hdr->sh_info)
1344
                                {
1345
                                  /* A local symbol.  */
1346
                                  asection *sym_sec;
1347
 
1348
                                  isym = isymbuf
1349
                                    + ELF32_R_SYM (rel->r_info);
1350
                                  sym_sec = bfd_section_from_elf_index
1351
                                    (abfd, isym->st_shndx);
1352
                                  symval = isym->st_value;
1353
 
1354
                                  /* If the reloc is absolute, it will not
1355
                                     have a symbol or section associated
1356
                                     with it.  */
1357
 
1358
                                  if (sym_sec)
1359
                                    {
1360
                                      symval +=
1361
                                        sym_sec->output_section->vma
1362
                                        + sym_sec->output_offset;
1363
                                      reloc_target = symval + rel->r_addend;
1364
                                    }
1365
                                  else
1366
                                    {
1367
                                      reloc_target = symval + rel->r_addend;
1368
                                      /* Reference symbol is absolute.  */
1369
                                    }
1370
                                }
1371
                              /* else, reference symbol is extern.  */
1372
 
1373
                              if (address_of_ret == reloc_target)
1374
                                {
1375
                                  deleting_ret_is_safe = 0;
1376
                                  if (debug_relax)
1377
                                    printf ("ret from "
1378
                                            "rjmp/jmp ret sequence at address"
1379
                                            " 0x%x could not be deleted.  ret"
1380
                                            " is target of a relocation.\n",
1381
                                            (int) address_of_ret);
1382
                                }
1383
                            }
1384
                        }
1385
 
1386
                        if (deleting_ret_is_safe)
1387
                          {
1388
                            if (debug_relax)
1389
                              printf ("unreachable ret instruction "
1390
                                      "at address 0x%x deleted.\n",
1391
                                      (int) dot + insn_size);
1392
 
1393
                            /* Delete two bytes of data.  */
1394
                            if (!elf32_open8_relax_delete_bytes (abfd,
1395
                                                                 sec,
1396
                                                                 irel->r_offset
1397
                                                                 + insn_size,
1398
                                                                 2))
1399
                              goto error_return;
1400
 
1401
                            /* That will change things, so, we should relax
1402
                               again.  Note that this is not required, and it
1403
                               may be slow.  */
1404
                            *again = TRUE;
1405
                            break;
1406
                          }
1407
                      }
1408
 
1409
                  }
1410
              }
1411
            break;
1412
          }
1413
        }
1414
    }
1415
 
1416
  if (contents != NULL
1417
      && elf_section_data (sec)->this_hdr.contents != contents)
1418
    {
1419
      if (! link_info->keep_memory)
1420
        free (contents);
1421
      else
1422
        {
1423
          /* Cache the section contents for elf_link_input_bfd.  */
1424
          elf_section_data (sec)->this_hdr.contents = contents;
1425
        }
1426
    }
1427
 
1428
  if (internal_relocs != NULL
1429
      && elf_section_data (sec)->relocs != internal_relocs)
1430
    free (internal_relocs);
1431
 
1432
  return TRUE;
1433
 
1434
 error_return:
1435
  if (isymbuf != NULL
1436
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1437
    free (isymbuf);
1438
  if (contents != NULL
1439
      && elf_section_data (sec)->this_hdr.contents != contents)
1440
    free (contents);
1441
  if (internal_relocs != NULL
1442
      && elf_section_data (sec)->relocs != internal_relocs)
1443
    free (internal_relocs);
1444
 
1445
  return FALSE;
1446
}
1447
 
1448
/* This is a version of bfd_generic_get_relocated_section_contents
1449
   which uses elf32_open8_relocate_section.
1450
 
1451
   For open8 it's essentially a cut and paste taken from the H8300 port.
1452
   The author of the relaxation support patch for open8 had absolutely no
1453
   clue what is happening here but found out that this part of the code
1454
   seems to be important.  */
1455
 
1456
static bfd_byte *
1457
elf32_open8_get_relocated_section_contents (bfd *output_bfd,
1458
                                            struct bfd_link_info *link_info,
1459
                                            struct bfd_link_order *link_order,
1460
                                            bfd_byte *data,
1461
                                            bfd_boolean relocatable,
1462
                                            asymbol **symbols)
1463
{
1464
  Elf_Internal_Shdr *symtab_hdr;
1465
  asection *input_section = link_order->u.indirect.section;
1466
  bfd *input_bfd = input_section->owner;
1467
  asection **sections = NULL;
1468
  Elf_Internal_Rela *internal_relocs = NULL;
1469
  Elf_Internal_Sym *isymbuf = NULL;
1470
 
1471
  /* We only need to handle the case of relaxing, or of having a
1472
     particular set of section contents, specially.  */
1473
  if (relocatable
1474
      || elf_section_data (input_section)->this_hdr.contents == NULL)
1475
    return bfd_generic_get_relocated_section_contents (output_bfd, link_info,
1476
                                                       link_order, data,
1477
                                                       relocatable,
1478
                                                       symbols);
1479
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1480
 
1481
  memcpy (data, elf_section_data (input_section)->this_hdr.contents,
1482
          (size_t) input_section->size);
1483
 
1484
  if ((input_section->flags & SEC_RELOC) != 0
1485
      && input_section->reloc_count > 0)
1486
    {
1487
      asection **secpp;
1488
      Elf_Internal_Sym *isym, *isymend;
1489
      bfd_size_type amt;
1490
 
1491
      internal_relocs = (_bfd_elf_link_read_relocs
1492
                         (input_bfd, input_section, NULL, NULL, FALSE));
1493
      if (internal_relocs == NULL)
1494
        goto error_return;
1495
 
1496
      if (symtab_hdr->sh_info != 0)
1497
        {
1498
          isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1499
          if (isymbuf == NULL)
1500
            isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1501
                                            symtab_hdr->sh_info, 0,
1502
                                            NULL, NULL, NULL);
1503
          if (isymbuf == NULL)
1504
            goto error_return;
1505
        }
1506
 
1507
      amt = symtab_hdr->sh_info;
1508
      amt *= sizeof (asection *);
1509
      sections = bfd_malloc (amt);
1510
      if (sections == NULL && amt != 0)
1511
        goto error_return;
1512
 
1513
      isymend = isymbuf + symtab_hdr->sh_info;
1514
      for (isym = isymbuf, secpp = sections; isym < isymend; ++isym, ++secpp)
1515
        {
1516
          asection *isec;
1517
 
1518
          if (isym->st_shndx == SHN_UNDEF)
1519
            isec = bfd_und_section_ptr;
1520
          else if (isym->st_shndx == SHN_ABS)
1521
            isec = bfd_abs_section_ptr;
1522
          else if (isym->st_shndx == SHN_COMMON)
1523
            isec = bfd_com_section_ptr;
1524
          else
1525
            isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
1526
 
1527
          *secpp = isec;
1528
        }
1529
 
1530
      if (! elf32_open8_relocate_section (output_bfd, link_info, input_bfd,
1531
                                          input_section, data, internal_relocs,
1532
                                          isymbuf, sections))
1533
        goto error_return;
1534
 
1535
      if (sections != NULL)
1536
        free (sections);
1537
      if (isymbuf != NULL
1538
          && symtab_hdr->contents != (unsigned char *) isymbuf)
1539
        free (isymbuf);
1540
      if (elf_section_data (input_section)->relocs != internal_relocs)
1541
        free (internal_relocs);
1542
    }
1543
 
1544
  return data;
1545
 
1546
 error_return:
1547
  if (sections != NULL)
1548
    free (sections);
1549
  if (isymbuf != NULL
1550
      && symtab_hdr->contents != (unsigned char *) isymbuf)
1551
    free (isymbuf);
1552
  if (internal_relocs != NULL
1553
      && elf_section_data (input_section)->relocs != internal_relocs)
1554
    free (internal_relocs);
1555
  return NULL;
1556
}
1557
 
1558
 
1559
/* Determines the hash entry name for a particular reloc.  It consists of
1560
   the identifier of the symbol section and the added reloc addend and
1561
   symbol offset relative to the section the symbol is attached to.  */
1562
 
1563
static char *
1564
open8_stub_name (const asection *symbol_section,
1565
                 const bfd_vma symbol_offset,
1566
                 const Elf_Internal_Rela *rela)
1567
{
1568
  char *stub_name;
1569
  bfd_size_type len;
1570
 
1571
  len = 8 + 1 + 8 + 1 + 1;
1572
  stub_name = bfd_malloc (len);
1573
 
1574
  snprintf (stub_name, len, "%08x+%08x",
1575
            symbol_section->id & 0xffffffff,
1576
            (unsigned int) ((rela->r_addend & 0xffffffff) + symbol_offset));
1577
 
1578
  return stub_name;
1579
}
1580
 
1581
 
1582
/* Add a new stub entry to the stub hash.  Not all fields of the new
1583
   stub entry are initialised.  */
1584
 
1585
static struct elf32_open8_stub_hash_entry *
1586
open8_add_stub (const char *stub_name,
1587
                struct elf32_open8_link_hash_table *htab)
1588
{
1589
  struct elf32_open8_stub_hash_entry *hsh;
1590
 
1591
  /* Enter this entry into the linker stub hash table.  */
1592
  hsh = open8_stub_hash_lookup (&htab->bstab, stub_name, TRUE, FALSE);
1593
 
1594
  if (hsh == NULL)
1595
    {
1596
      (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
1597
                             NULL, stub_name);
1598
      return NULL;
1599
    }
1600
 
1601
  hsh->stub_offset = 0;
1602
  return hsh;
1603
}
1604
 
1605
/* We assume that there is already space allocated for the stub section
1606
   contents and that before building the stubs the section size is
1607
   initialized to 0.  We assume that within the stub hash table entry,
1608
   the absolute position of the jmp target has been written in the
1609
   target_value field.  We write here the offset of the generated jmp insn
1610
   relative to the trampoline section start to the stub_offset entry in
1611
   the stub hash table entry.  */
1612
 
1613
static  bfd_boolean
1614
open8_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
1615
{
1616
  struct elf32_open8_stub_hash_entry *hsh;
1617
  struct bfd_link_info *info;
1618
  struct elf32_open8_link_hash_table *htab;
1619
  bfd *stub_bfd;
1620
  bfd_byte *loc;
1621
  bfd_vma target;
1622
  bfd_vma starget;
1623
 
1624
  /* Basic opcode.  */
1625
  bfd_vma jmp_insn = 0x0000940c;
1626
 
1627
  /* Massage our args to the form they really have.  */
1628
  hsh = open8_stub_hash_entry (bh);
1629
 
1630
  if (!hsh->is_actually_needed)
1631
    return TRUE;
1632
 
1633
  info = (struct bfd_link_info *) in_arg;
1634
 
1635
  htab = open8_link_hash_table (info);
1636
  if (htab == NULL)
1637
    return FALSE;
1638
 
1639
  target = hsh->target_value;
1640
 
1641
  /* Make a note of the offset within the stubs for this entry.  */
1642
  hsh->stub_offset = htab->stub_sec->size;
1643
  loc = htab->stub_sec->contents + hsh->stub_offset;
1644
 
1645
  stub_bfd = htab->stub_sec->owner;
1646
 
1647
  if (debug_stubs)
1648
    printf ("Building one Stub.  Address: 0x%x, Offset: 0x%x\n",
1649
            (unsigned int) target,
1650
            (unsigned int) hsh->stub_offset);
1651
 
1652
  /* We now have to add the information on the jump target to the bare
1653
     opcode bits already set in jmp_insn.  */
1654
 
1655
  /* Check for the alignment of the address.  */
1656
  if (target & 1)
1657
    return FALSE;
1658
 
1659
  starget = target >> 1;
1660
  jmp_insn |= ((starget & 0x10000) | ((starget << 3) & 0x1f00000)) >> 16;
1661
  bfd_put_16 (stub_bfd, jmp_insn, loc);
1662
  bfd_put_16 (stub_bfd, (bfd_vma) starget & 0xffff, loc + 2);
1663
 
1664
  htab->stub_sec->size += 4;
1665
 
1666
  /* Now add the entries in the address mapping table if there is still
1667
     space left.  */
1668
  {
1669
    unsigned int nr;
1670
 
1671
    nr = htab->amt_entry_cnt + 1;
1672
    if (nr <= htab->amt_max_entry_cnt)
1673
      {
1674
        htab->amt_entry_cnt = nr;
1675
 
1676
        htab->amt_stub_offsets[nr - 1] = hsh->stub_offset;
1677
        htab->amt_destination_addr[nr - 1] = target;
1678
      }
1679
  }
1680
 
1681
  return TRUE;
1682
}
1683
 
1684
static bfd_boolean
1685
open8_mark_stub_not_to_be_necessary (struct bfd_hash_entry *bh,
1686
                                     void *in_arg ATTRIBUTE_UNUSED)
1687
{
1688
  struct elf32_open8_stub_hash_entry *hsh;
1689
 
1690
  hsh = open8_stub_hash_entry (bh);
1691
  hsh->is_actually_needed = FALSE;
1692
 
1693
  return TRUE;
1694
}
1695
 
1696
static bfd_boolean
1697
open8_size_one_stub (struct bfd_hash_entry *bh, void *in_arg)
1698
{
1699
  struct elf32_open8_stub_hash_entry *hsh;
1700
  struct elf32_open8_link_hash_table *htab;
1701
  int size;
1702
 
1703
  /* Massage our args to the form they really have.  */
1704
  hsh = open8_stub_hash_entry (bh);
1705
  htab = in_arg;
1706
 
1707
  if (hsh->is_actually_needed)
1708
    size = 4;
1709
  else
1710
    size = 0;
1711
 
1712
  htab->stub_sec->size += size;
1713
  return TRUE;
1714
}
1715
 
1716
void
1717
elf32_open8_setup_params (struct bfd_link_info *info,
1718
                          bfd *open8_stub_bfd,
1719
                          asection *open8_stub_section,
1720
                          bfd_boolean no_stubs,
1721
                          bfd_boolean deb_stubs,
1722
                          bfd_boolean deb_relax,
1723
                          bfd_vma pc_wrap_around,
1724
                          bfd_boolean call_ret_replacement)
1725
{
1726
  struct elf32_open8_link_hash_table *htab = open8_link_hash_table (info);
1727
 
1728
  if (htab == NULL)
1729
    return;
1730
  htab->stub_sec = open8_stub_section;
1731
  htab->stub_bfd = open8_stub_bfd;
1732
  htab->no_stubs = no_stubs;
1733
 
1734
  debug_relax = deb_relax;
1735
  debug_stubs = deb_stubs;
1736
  open8_pc_wrap_around = pc_wrap_around;
1737
  open8_replace_call_ret_sequences = call_ret_replacement;
1738
}
1739
 
1740
 
1741
/* Set up various things so that we can make a list of input sections
1742
   for each output section included in the link.  Returns -1 on error,
1743
 
1744
   information on the stubs bfd and the stub section in the info
1745
   struct.  */
1746
 
1747
int
1748
elf32_open8_setup_section_lists (bfd *output_bfd,
1749
                                 struct bfd_link_info *info)
1750
{
1751
  bfd *input_bfd;
1752
  unsigned int bfd_count;
1753
  int top_id, top_index;
1754
  asection *section;
1755
  asection **input_list, **list;
1756
  bfd_size_type amt;
1757
  struct elf32_open8_link_hash_table *htab = open8_link_hash_table (info);
1758
 
1759
  if (htab == NULL || htab->no_stubs)
1760
    return 0;
1761
 
1762
  /* Count the number of input BFDs and find the top input section id.  */
1763
  for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
1764
       input_bfd != NULL;
1765
       input_bfd = input_bfd->link_next)
1766
    {
1767
      bfd_count += 1;
1768
      for (section = input_bfd->sections;
1769
           section != NULL;
1770
           section = section->next)
1771
        if (top_id < section->id)
1772
          top_id = section->id;
1773
    }
1774
 
1775
  htab->bfd_count = bfd_count;
1776
 
1777
  /* We can't use output_bfd->section_count here to find the top output
1778
     section index as some sections may have been removed, and
1779
     strip_excluded_output_sections doesn't renumber the indices.  */
1780
  for (section = output_bfd->sections, top_index = 0;
1781
       section != NULL;
1782
       section = section->next)
1783
    if (top_index < section->index)
1784
      top_index = section->index;
1785
 
1786
  htab->top_index = top_index;
1787
  amt = sizeof (asection *) * (top_index + 1);
1788
  input_list = bfd_malloc (amt);
1789
  htab->input_list = input_list;
1790
  if (input_list == NULL)
1791
    return -1;
1792
 
1793
  /* For sections we aren't interested in, mark their entries with a
1794
     value we can check later.  */
1795
  list = input_list + top_index;
1796
  do
1797
    *list = bfd_abs_section_ptr;
1798
  while (list-- != input_list);
1799
 
1800
  for (section = output_bfd->sections;
1801
       section != NULL;
1802
       section = section->next)
1803
    if ((section->flags & SEC_CODE) != 0)
1804
      input_list[section->index] = NULL;
1805
 
1806
  return 1;
1807
}
1808
 
1809
 
1810
/* Read in all local syms for all input bfds, and create hash entries
1811
   for export stubs if we are building a multi-subspace shared lib.
1812
   Returns -1 on error, 0 otherwise.  */
1813
 
1814
static int
1815
get_local_syms (bfd *input_bfd, struct bfd_link_info *info)
1816
{
1817
  unsigned int bfd_indx;
1818
  Elf_Internal_Sym *local_syms, **all_local_syms;
1819
  struct elf32_open8_link_hash_table *htab = open8_link_hash_table (info);
1820
  bfd_size_type amt;
1821
 
1822
  if (htab == NULL)
1823
    return -1;
1824
 
1825
  /* We want to read in symbol extension records only once.  To do this
1826
     we need to read in the local symbols in parallel and save them for
1827
     later use; so hold pointers to the local symbols in an array.  */
1828
  amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
1829
  all_local_syms = bfd_zmalloc (amt);
1830
  htab->all_local_syms = all_local_syms;
1831
  if (all_local_syms == NULL)
1832
    return -1;
1833
 
1834
  /* Walk over all the input BFDs, swapping in local symbols.
1835
     If we are creating a shared library, create hash entries for the
1836
     export stubs.  */
1837
  for (bfd_indx = 0;
1838
       input_bfd != NULL;
1839
       input_bfd = input_bfd->link_next, bfd_indx++)
1840
    {
1841
      Elf_Internal_Shdr *symtab_hdr;
1842
 
1843
      /* We'll need the symbol table in a second.  */
1844
      symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1845
      if (symtab_hdr->sh_info == 0)
1846
        continue;
1847
 
1848
      /* We need an array of the local symbols attached to the input bfd.  */
1849
      local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
1850
      if (local_syms == NULL)
1851
        {
1852
          local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1853
                                             symtab_hdr->sh_info, 0,
1854
                                             NULL, NULL, NULL);
1855
          /* Cache them for elf_link_input_bfd.  */
1856
          symtab_hdr->contents = (unsigned char *) local_syms;
1857
        }
1858
      if (local_syms == NULL)
1859
        return -1;
1860
 
1861
      all_local_syms[bfd_indx] = local_syms;
1862
    }
1863
 
1864
  return 0;
1865
}
1866
 
1867
#define ADD_DUMMY_STUBS_FOR_DEBUGGING 0
1868
 
1869
bfd_boolean
1870
elf32_open8_size_stubs (bfd *output_bfd,
1871
                        struct bfd_link_info *info,
1872
                        bfd_boolean is_prealloc_run)
1873
{
1874
  struct elf32_open8_link_hash_table *htab;
1875
  int stub_changed = 0;
1876
 
1877
  htab = open8_link_hash_table (info);
1878
  if (htab == NULL)
1879
    return FALSE;
1880
 
1881
  /* At this point we initialize htab->vector_base
1882
     To the start of the text output section.  */
1883
  htab->vector_base = htab->stub_sec->output_section->vma;
1884
 
1885
  if (get_local_syms (info->input_bfds, info))
1886
    {
1887
      if (htab->all_local_syms)
1888
        goto error_ret_free_local;
1889
      return FALSE;
1890
    }
1891
 
1892
  if (ADD_DUMMY_STUBS_FOR_DEBUGGING)
1893
    {
1894
      struct elf32_open8_stub_hash_entry *test;
1895
 
1896
      test = open8_add_stub ("Hugo",htab);
1897
      test->target_value = 0x123456;
1898
      test->stub_offset = 13;
1899
 
1900
      test = open8_add_stub ("Hugo2",htab);
1901
      test->target_value = 0x84210;
1902
      test->stub_offset = 14;
1903
    }
1904
 
1905
  while (1)
1906
    {
1907
      bfd *input_bfd;
1908
      unsigned int bfd_indx;
1909
 
1910
      /* We will have to re-generate the stub hash table each time anything
1911
         in memory has changed.  */
1912
 
1913
      bfd_hash_traverse (&htab->bstab,
1914
                         open8_mark_stub_not_to_be_necessary,
1915
                         htab);
1916
      for (input_bfd = info->input_bfds, bfd_indx = 0;
1917
           input_bfd != NULL;
1918
           input_bfd = input_bfd->link_next, bfd_indx++)
1919
        {
1920
          Elf_Internal_Shdr *symtab_hdr;
1921
          asection *section;
1922
          Elf_Internal_Sym *local_syms;
1923
 
1924
          /* We'll need the symbol table in a second.  */
1925
          symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1926
          if (symtab_hdr->sh_info == 0)
1927
            continue;
1928
 
1929
          local_syms = htab->all_local_syms[bfd_indx];
1930
 
1931
          /* Walk over each section attached to the input bfd.  */
1932
          for (section = input_bfd->sections;
1933
               section != NULL;
1934
               section = section->next)
1935
            {
1936
              Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
1937
 
1938
              /* If there aren't any relocs, then there's nothing more
1939
                 to do.  */
1940
              if ((section->flags & SEC_RELOC) == 0
1941
                  || section->reloc_count == 0)
1942
                continue;
1943
 
1944
              /* If this section is a link-once section that will be
1945
                 discarded, then don't create any stubs.  */
1946
              if (section->output_section == NULL
1947
                  || section->output_section->owner != output_bfd)
1948
                continue;
1949
 
1950
              /* Get the relocs.  */
1951
              internal_relocs = _bfd_elf_link_read_relocs (input_bfd,
1952
                                                           section,
1953
                                                           NULL,
1954
                                                           NULL,
1955
                                                           info->keep_memory);
1956
              if (internal_relocs == NULL)
1957
                goto error_ret_free_local;
1958
 
1959
              /* Now examine each relocation.  */
1960
              irela = internal_relocs;
1961
              irelaend = irela + section->reloc_count;
1962
              for (; irela < irelaend; irela++)
1963
                {
1964 165 khays
                  unsigned int r_indx;
1965 14 khays
                  struct elf32_open8_stub_hash_entry *hsh;
1966
                  asection *sym_sec;
1967
                  bfd_vma sym_value;
1968
                  bfd_vma destination;
1969
                  struct elf_link_hash_entry *hh;
1970
                  char *stub_name;
1971
 
1972
                  r_indx = ELF32_R_SYM (irela->r_info);
1973
 
1974
                  /* Now determine the call target, its name, value,
1975
                     section.  */
1976
                  sym_sec = NULL;
1977
                  sym_value = 0;
1978
                  destination = 0;
1979
                  hh = NULL;
1980
                  if (r_indx < symtab_hdr->sh_info)
1981
                    {
1982
                      /* It's a local symbol.  */
1983
                      Elf_Internal_Sym *sym;
1984
                      Elf_Internal_Shdr *hdr;
1985
                      unsigned int shndx;
1986
 
1987
                      sym = local_syms + r_indx;
1988
                      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
1989
                        sym_value = sym->st_value;
1990
                      shndx = sym->st_shndx;
1991
                      if (shndx < elf_numsections (input_bfd))
1992
                        {
1993
                          hdr = elf_elfsections (input_bfd)[shndx];
1994
                          sym_sec = hdr->bfd_section;
1995
                          destination = (sym_value + irela->r_addend
1996
                                         + sym_sec->output_offset
1997
                                         + sym_sec->output_section->vma);
1998
                        }
1999
                    }
2000
                  else
2001
                    {
2002
                      /* It's an external symbol.  */
2003
                      int e_indx;
2004
 
2005
                      e_indx = r_indx - symtab_hdr->sh_info;
2006
                      hh = elf_sym_hashes (input_bfd)[e_indx];
2007
 
2008
                      while (hh->root.type == bfd_link_hash_indirect
2009
                             || hh->root.type == bfd_link_hash_warning)
2010
                        hh = (struct elf_link_hash_entry *)
2011
                          (hh->root.u.i.link);
2012
 
2013
                      if (hh->root.type == bfd_link_hash_defined
2014
                          || hh->root.type == bfd_link_hash_defweak)
2015
                        {
2016
                          sym_sec = hh->root.u.def.section;
2017
                          sym_value = hh->root.u.def.value;
2018
                          if (sym_sec->output_section != NULL)
2019
                            destination = (sym_value + irela->r_addend
2020
                                           + sym_sec->output_offset
2021
                                           + sym_sec->output_section->vma);
2022
                        }
2023
                      else if (hh->root.type == bfd_link_hash_undefweak)
2024
                        {
2025
                          if (! info->shared)
2026
                            continue;
2027
                        }
2028
                      else if (hh->root.type == bfd_link_hash_undefined)
2029
                        {
2030
                          if (! (info->unresolved_syms_in_objects == RM_IGNORE
2031
                                 && (ELF_ST_VISIBILITY (hh->other)
2032
                                     == STV_DEFAULT)))
2033
                            continue;
2034
                        }
2035
                      else
2036
                        {
2037
                          bfd_set_error (bfd_error_bad_value);
2038
 
2039
                        error_ret_free_internal:
2040
                          if (elf_section_data (section)->relocs == NULL)
2041
                            free (internal_relocs);
2042
                          goto error_ret_free_local;
2043
                        }
2044
                    }
2045
 
2046
                  if (! open8_stub_is_required_for_16_bit_reloc
2047
                      (destination - htab->vector_base))
2048
                    {
2049
                      if (!is_prealloc_run)
2050
                        /* We are having a reloc that does't need a stub.  */
2051
                        continue;
2052
 
2053
                      /* We don't right now know if a stub will be needed.
2054
                         Let's rather be on the safe side.  */
2055
                    }
2056
 
2057
                  /* Get the name of this stub.  */
2058
                  stub_name = open8_stub_name (sym_sec, sym_value, irela);
2059
 
2060
                  if (!stub_name)
2061
                    goto error_ret_free_internal;
2062
 
2063
 
2064
                  hsh = open8_stub_hash_lookup (&htab->bstab,
2065
                                                stub_name,
2066
                                                FALSE, FALSE);
2067
                  if (hsh != NULL)
2068
                    {
2069
                      /* The proper stub has already been created.  Mark it
2070
                         to be used and write the possibly changed destination
2071
                         value.  */
2072
                      hsh->is_actually_needed = TRUE;
2073
                      hsh->target_value = destination;
2074
                      free (stub_name);
2075
                      continue;
2076
                    }
2077
 
2078
                  hsh = open8_add_stub (stub_name, htab);
2079
                  if (hsh == NULL)
2080
                    {
2081
                      free (stub_name);
2082
                      goto error_ret_free_internal;
2083
                    }
2084
 
2085
                  hsh->is_actually_needed = TRUE;
2086
                  hsh->target_value = destination;
2087
 
2088
                  if (debug_stubs)
2089
                    printf ("Adding stub with destination 0x%x to the"
2090
                            " hash table.\n", (unsigned int) destination);
2091
                  if (debug_stubs)
2092
                    printf ("(Pre-Alloc run: %i)\n", is_prealloc_run);
2093
 
2094
                  stub_changed = TRUE;
2095
                }
2096
 
2097
              /* We're done with the internal relocs, free them.  */
2098
              if (elf_section_data (section)->relocs == NULL)
2099
                free (internal_relocs);
2100
            }
2101
        }
2102
 
2103
      /* Re-Calculate the number of needed stubs.  */
2104
      htab->stub_sec->size = 0;
2105
      bfd_hash_traverse (&htab->bstab, open8_size_one_stub, htab);
2106
 
2107
      if (!stub_changed)
2108
        break;
2109
 
2110
      stub_changed = FALSE;
2111
    }
2112
 
2113
  free (htab->all_local_syms);
2114
  return TRUE;
2115
 
2116
 error_ret_free_local:
2117
  free (htab->all_local_syms);
2118
  return FALSE;
2119
}
2120
 
2121
 
2122
/* Build all the stubs associated with the current output file.  The
2123
   stubs are kept in a hash table attached to the main linker hash
2124
   table.  We also set up the `.plt' entries for statically linked PIC
2125
   functions here.  This function is called via hppaelf_finish in the
2126
   linker.  */
2127
 
2128
bfd_boolean
2129
elf32_open8_build_stubs (struct bfd_link_info *info)
2130
{
2131
  asection *stub_sec;
2132
  struct bfd_hash_table *table;
2133
  struct elf32_open8_link_hash_table *htab;
2134
  bfd_size_type total_size = 0;
2135
 
2136
  htab = open8_link_hash_table (info);
2137
  if (htab == NULL)
2138
    return FALSE;
2139
 
2140
  /* In case that there were several stub sections: */
2141
  for (stub_sec = htab->stub_bfd->sections;
2142
       stub_sec != NULL;
2143
       stub_sec = stub_sec->next)
2144
    {
2145
      bfd_size_type size;
2146
 
2147
      /* Allocate memory to hold the linker stubs.  */
2148
      size = stub_sec->size;
2149
      total_size += size;
2150
 
2151
      stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
2152
      if (stub_sec->contents == NULL && size != 0)
2153
        return FALSE;
2154
      stub_sec->size = 0;
2155
    }
2156
 
2157
  /* Allocate memory for the address mapping table.  */
2158
  htab->amt_entry_cnt = 0;
2159
  htab->amt_max_entry_cnt = total_size / 4;
2160
  htab->amt_stub_offsets = bfd_malloc (sizeof (bfd_vma)
2161
                                       * htab->amt_max_entry_cnt);
2162
  htab->amt_destination_addr = bfd_malloc (sizeof (bfd_vma)
2163
                                           * htab->amt_max_entry_cnt);
2164
 
2165
  if (debug_stubs)
2166
    printf ("Allocating %i entries in the AMT\n", htab->amt_max_entry_cnt);
2167
 
2168
  /* Build the stubs as directed by the stub hash table.  */
2169
  table = &htab->bstab;
2170
  bfd_hash_traverse (table, open8_build_one_stub, info);
2171
 
2172
  if (debug_stubs)
2173
    printf ("Final Stub section Size: %i\n", (int) htab->stub_sec->size);
2174
 
2175
  return TRUE;
2176
}
2177
 
2178
#define ELF_ARCH                bfd_arch_open8
2179
#define ELF_TARGET_ID           OPEN8_ELF_DATA
2180
#define ELF_MACHINE_CODE        EM_OPEN8
2181
#define ELF_MAXPAGESIZE         1
2182
 
2183
#define TARGET_LITTLE_SYM       bfd_elf32_open8_vec
2184
#define TARGET_LITTLE_NAME      "elf32-open8"
2185
 
2186
#define bfd_elf32_bfd_link_hash_table_create elf32_open8_link_hash_table_create
2187
#define bfd_elf32_bfd_link_hash_table_free   elf32_open8_link_hash_table_free
2188
 
2189
#define elf_info_to_howto                    open8_info_to_howto_rela
2190
#define elf_info_to_howto_rel                NULL
2191
#define elf_backend_relocate_section         elf32_open8_relocate_section
2192
#define elf_backend_can_gc_sections          1
2193
#define elf_backend_rela_normal              1
2194
#define elf_backend_final_write_processing      \
2195
  bfd_elf_open8_final_write_processing
2196
#define elf_backend_object_p            elf32_open8_object_p
2197
 
2198
#define bfd_elf32_bfd_relax_section elf32_open8_relax_section
2199
#define bfd_elf32_bfd_get_relocated_section_contents    \
2200
  elf32_open8_get_relocated_section_contents
2201
 
2202
#include "elf32-target.h"

powered by: WebSVN 2.1.0

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