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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [bfd/] [elf-eh-frame.c] - Blame information for rev 161

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 khays
/* .eh_frame section optimization.
2 161 khays
   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
3 14 khays
   Free Software Foundation, Inc.
4
   Written by Jakub Jelinek <jakub@redhat.com>.
5
 
6
   This file is part of BFD, the Binary File Descriptor library.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
 
23
#include "sysdep.h"
24
#include "bfd.h"
25
#include "libbfd.h"
26
#include "elf-bfd.h"
27
#include "dwarf2.h"
28
 
29
#define EH_FRAME_HDR_SIZE 8
30
 
31
struct cie
32
{
33
  unsigned int length;
34
  unsigned int hash;
35
  unsigned char version;
36
  unsigned char local_personality;
37
  char augmentation[20];
38
  bfd_vma code_align;
39
  bfd_signed_vma data_align;
40
  bfd_vma ra_column;
41
  bfd_vma augmentation_size;
42
  union {
43
    struct elf_link_hash_entry *h;
44
    bfd_vma val;
45
    unsigned int reloc_index;
46
  } personality;
47
  asection *output_sec;
48
  struct eh_cie_fde *cie_inf;
49
  unsigned char per_encoding;
50
  unsigned char lsda_encoding;
51
  unsigned char fde_encoding;
52
  unsigned char initial_insn_length;
53
  unsigned char can_make_lsda_relative;
54
  unsigned char initial_instructions[50];
55
};
56
 
57
 
58
 
59
/* If *ITER hasn't reached END yet, read the next byte into *RESULT and
60
   move onto the next byte.  Return true on success.  */
61
 
62
static inline bfd_boolean
63
read_byte (bfd_byte **iter, bfd_byte *end, unsigned char *result)
64
{
65
  if (*iter >= end)
66
    return FALSE;
67
  *result = *((*iter)++);
68
  return TRUE;
69
}
70
 
71
/* Move *ITER over LENGTH bytes, or up to END, whichever is closer.
72
   Return true it was possible to move LENGTH bytes.  */
73
 
74
static inline bfd_boolean
75
skip_bytes (bfd_byte **iter, bfd_byte *end, bfd_size_type length)
76
{
77
  if ((bfd_size_type) (end - *iter) < length)
78
    {
79
      *iter = end;
80
      return FALSE;
81
    }
82
  *iter += length;
83
  return TRUE;
84
}
85
 
86
/* Move *ITER over an leb128, stopping at END.  Return true if the end
87
   of the leb128 was found.  */
88
 
89
static bfd_boolean
90
skip_leb128 (bfd_byte **iter, bfd_byte *end)
91
{
92
  unsigned char byte;
93
  do
94
    if (!read_byte (iter, end, &byte))
95
      return FALSE;
96
  while (byte & 0x80);
97
  return TRUE;
98
}
99
 
100
/* Like skip_leb128, but treat the leb128 as an unsigned value and
101
   store it in *VALUE.  */
102
 
103
static bfd_boolean
104
read_uleb128 (bfd_byte **iter, bfd_byte *end, bfd_vma *value)
105
{
106
  bfd_byte *start, *p;
107
 
108
  start = *iter;
109
  if (!skip_leb128 (iter, end))
110
    return FALSE;
111
 
112
  p = *iter;
113
  *value = *--p;
114
  while (p > start)
115
    *value = (*value << 7) | (*--p & 0x7f);
116
 
117
  return TRUE;
118
}
119
 
120
/* Like read_uleb128, but for signed values.  */
121
 
122
static bfd_boolean
123
read_sleb128 (bfd_byte **iter, bfd_byte *end, bfd_signed_vma *value)
124
{
125
  bfd_byte *start, *p;
126
 
127
  start = *iter;
128
  if (!skip_leb128 (iter, end))
129
    return FALSE;
130
 
131
  p = *iter;
132
  *value = ((*--p & 0x7f) ^ 0x40) - 0x40;
133
  while (p > start)
134
    *value = (*value << 7) | (*--p & 0x7f);
135
 
136
  return TRUE;
137
}
138
 
139
/* Return 0 if either encoding is variable width, or not yet known to bfd.  */
140
 
141
static
142
int get_DW_EH_PE_width (int encoding, int ptr_size)
143
{
144
  /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame
145
     was added to bfd.  */
146
  if ((encoding & 0x60) == 0x60)
147
    return 0;
148
 
149
  switch (encoding & 7)
150
    {
151
    case DW_EH_PE_udata2: return 2;
152
    case DW_EH_PE_udata4: return 4;
153
    case DW_EH_PE_udata8: return 8;
154
    case DW_EH_PE_absptr: return ptr_size;
155
    default:
156
      break;
157
    }
158
 
159
  return 0;
160
}
161
 
162
#define get_DW_EH_PE_signed(encoding) (((encoding) & DW_EH_PE_signed) != 0)
163
 
164
/* Read a width sized value from memory.  */
165
 
166
static bfd_vma
167
read_value (bfd *abfd, bfd_byte *buf, int width, int is_signed)
168
{
169
  bfd_vma value;
170
 
171
  switch (width)
172
    {
173
    case 2:
174
      if (is_signed)
175
        value = bfd_get_signed_16 (abfd, buf);
176
      else
177
        value = bfd_get_16 (abfd, buf);
178
      break;
179
    case 4:
180
      if (is_signed)
181
        value = bfd_get_signed_32 (abfd, buf);
182
      else
183
        value = bfd_get_32 (abfd, buf);
184
      break;
185
    case 8:
186
      if (is_signed)
187
        value = bfd_get_signed_64 (abfd, buf);
188
      else
189
        value = bfd_get_64 (abfd, buf);
190
      break;
191
    default:
192
      BFD_FAIL ();
193
      return 0;
194
    }
195
 
196
  return value;
197
}
198
 
199
/* Store a width sized value to memory.  */
200
 
201
static void
202
write_value (bfd *abfd, bfd_byte *buf, bfd_vma value, int width)
203
{
204
  switch (width)
205
    {
206
    case 2: bfd_put_16 (abfd, value, buf); break;
207
    case 4: bfd_put_32 (abfd, value, buf); break;
208
    case 8: bfd_put_64 (abfd, value, buf); break;
209
    default: BFD_FAIL ();
210
    }
211
}
212
 
213
/* Return one if C1 and C2 CIEs can be merged.  */
214
 
215
static int
216
cie_eq (const void *e1, const void *e2)
217
{
218
  const struct cie *c1 = (const struct cie *) e1;
219
  const struct cie *c2 = (const struct cie *) e2;
220
 
221
  if (c1->hash == c2->hash
222
      && c1->length == c2->length
223
      && c1->version == c2->version
224
      && c1->local_personality == c2->local_personality
225
      && strcmp (c1->augmentation, c2->augmentation) == 0
226
      && strcmp (c1->augmentation, "eh") != 0
227
      && c1->code_align == c2->code_align
228
      && c1->data_align == c2->data_align
229
      && c1->ra_column == c2->ra_column
230
      && c1->augmentation_size == c2->augmentation_size
231
      && memcmp (&c1->personality, &c2->personality,
232
                 sizeof (c1->personality)) == 0
233
      && c1->output_sec == c2->output_sec
234
      && c1->per_encoding == c2->per_encoding
235
      && c1->lsda_encoding == c2->lsda_encoding
236
      && c1->fde_encoding == c2->fde_encoding
237
      && c1->initial_insn_length == c2->initial_insn_length
238
      && memcmp (c1->initial_instructions,
239
                 c2->initial_instructions,
240
                 c1->initial_insn_length) == 0)
241
    return 1;
242
 
243
  return 0;
244
}
245
 
246
static hashval_t
247
cie_hash (const void *e)
248
{
249
  const struct cie *c = (const struct cie *) e;
250
  return c->hash;
251
}
252
 
253
static hashval_t
254
cie_compute_hash (struct cie *c)
255
{
256
  hashval_t h = 0;
257
  h = iterative_hash_object (c->length, h);
258
  h = iterative_hash_object (c->version, h);
259
  h = iterative_hash (c->augmentation, strlen (c->augmentation) + 1, h);
260
  h = iterative_hash_object (c->code_align, h);
261
  h = iterative_hash_object (c->data_align, h);
262
  h = iterative_hash_object (c->ra_column, h);
263
  h = iterative_hash_object (c->augmentation_size, h);
264
  h = iterative_hash_object (c->personality, h);
265
  h = iterative_hash_object (c->output_sec, h);
266
  h = iterative_hash_object (c->per_encoding, h);
267
  h = iterative_hash_object (c->lsda_encoding, h);
268
  h = iterative_hash_object (c->fde_encoding, h);
269
  h = iterative_hash_object (c->initial_insn_length, h);
270
  h = iterative_hash (c->initial_instructions, c->initial_insn_length, h);
271
  c->hash = h;
272
  return h;
273
}
274
 
275
/* Return the number of extra bytes that we'll be inserting into
276
   ENTRY's augmentation string.  */
277
 
278
static INLINE unsigned int
279
extra_augmentation_string_bytes (struct eh_cie_fde *entry)
280
{
281
  unsigned int size = 0;
282
  if (entry->cie)
283
    {
284
      if (entry->add_augmentation_size)
285
        size++;
286
      if (entry->u.cie.add_fde_encoding)
287
        size++;
288
    }
289
  return size;
290
}
291
 
292
/* Likewise ENTRY's augmentation data.  */
293
 
294
static INLINE unsigned int
295
extra_augmentation_data_bytes (struct eh_cie_fde *entry)
296
{
297
  unsigned int size = 0;
298
  if (entry->add_augmentation_size)
299
    size++;
300
  if (entry->cie && entry->u.cie.add_fde_encoding)
301
    size++;
302
  return size;
303
}
304
 
305
/* Return the size that ENTRY will have in the output.  ALIGNMENT is the
306
   required alignment of ENTRY in bytes.  */
307
 
308
static unsigned int
309
size_of_output_cie_fde (struct eh_cie_fde *entry, unsigned int alignment)
310
{
311
  if (entry->removed)
312
    return 0;
313
  if (entry->size == 4)
314
    return 4;
315
  return (entry->size
316
          + extra_augmentation_string_bytes (entry)
317
          + extra_augmentation_data_bytes (entry)
318
          + alignment - 1) & -alignment;
319
}
320
 
321
/* Assume that the bytes between *ITER and END are CFA instructions.
322
   Try to move *ITER past the first instruction and return true on
323
   success.  ENCODED_PTR_WIDTH gives the width of pointer entries.  */
324
 
325
static bfd_boolean
326
skip_cfa_op (bfd_byte **iter, bfd_byte *end, unsigned int encoded_ptr_width)
327
{
328
  bfd_byte op;
329
  bfd_vma length;
330
 
331
  if (!read_byte (iter, end, &op))
332
    return FALSE;
333
 
334
  switch (op & 0xc0 ? op & 0xc0 : op)
335
    {
336
    case DW_CFA_nop:
337
    case DW_CFA_advance_loc:
338
    case DW_CFA_restore:
339
    case DW_CFA_remember_state:
340
    case DW_CFA_restore_state:
341
    case DW_CFA_GNU_window_save:
342
      /* No arguments.  */
343
      return TRUE;
344
 
345
    case DW_CFA_offset:
346
    case DW_CFA_restore_extended:
347
    case DW_CFA_undefined:
348
    case DW_CFA_same_value:
349
    case DW_CFA_def_cfa_register:
350
    case DW_CFA_def_cfa_offset:
351
    case DW_CFA_def_cfa_offset_sf:
352
    case DW_CFA_GNU_args_size:
353
      /* One leb128 argument.  */
354
      return skip_leb128 (iter, end);
355
 
356
    case DW_CFA_val_offset:
357
    case DW_CFA_val_offset_sf:
358
    case DW_CFA_offset_extended:
359
    case DW_CFA_register:
360
    case DW_CFA_def_cfa:
361
    case DW_CFA_offset_extended_sf:
362
    case DW_CFA_GNU_negative_offset_extended:
363
    case DW_CFA_def_cfa_sf:
364
      /* Two leb128 arguments.  */
365
      return (skip_leb128 (iter, end)
366
              && skip_leb128 (iter, end));
367
 
368
    case DW_CFA_def_cfa_expression:
369
      /* A variable-length argument.  */
370
      return (read_uleb128 (iter, end, &length)
371
              && skip_bytes (iter, end, length));
372
 
373
    case DW_CFA_expression:
374
    case DW_CFA_val_expression:
375
      /* A leb128 followed by a variable-length argument.  */
376
      return (skip_leb128 (iter, end)
377
              && read_uleb128 (iter, end, &length)
378
              && skip_bytes (iter, end, length));
379
 
380
    case DW_CFA_set_loc:
381
      return skip_bytes (iter, end, encoded_ptr_width);
382
 
383
    case DW_CFA_advance_loc1:
384
      return skip_bytes (iter, end, 1);
385
 
386
    case DW_CFA_advance_loc2:
387
      return skip_bytes (iter, end, 2);
388
 
389
    case DW_CFA_advance_loc4:
390
      return skip_bytes (iter, end, 4);
391
 
392
    case DW_CFA_MIPS_advance_loc8:
393
      return skip_bytes (iter, end, 8);
394
 
395
    default:
396
      return FALSE;
397
    }
398
}
399
 
400
/* Try to interpret the bytes between BUF and END as CFA instructions.
401
   If every byte makes sense, return a pointer to the first DW_CFA_nop
402
   padding byte, or END if there is no padding.  Return null otherwise.
403
   ENCODED_PTR_WIDTH is as for skip_cfa_op.  */
404
 
405
static bfd_byte *
406
skip_non_nops (bfd_byte *buf, bfd_byte *end, unsigned int encoded_ptr_width,
407
               unsigned int *set_loc_count)
408
{
409
  bfd_byte *last;
410
 
411
  last = buf;
412
  while (buf < end)
413
    if (*buf == DW_CFA_nop)
414
      buf++;
415
    else
416
      {
417
        if (*buf == DW_CFA_set_loc)
418
          ++*set_loc_count;
419
        if (!skip_cfa_op (&buf, end, encoded_ptr_width))
420
          return 0;
421
        last = buf;
422
      }
423
  return last;
424
}
425
 
426
/* Convert absolute encoding ENCODING into PC-relative form.
427
   SIZE is the size of a pointer.  */
428
 
429
static unsigned char
430
make_pc_relative (unsigned char encoding, unsigned int ptr_size)
431
{
432
  if ((encoding & 0x7f) == DW_EH_PE_absptr)
433
    switch (ptr_size)
434
      {
435
      case 2:
436
        encoding |= DW_EH_PE_sdata2;
437
        break;
438
      case 4:
439
        encoding |= DW_EH_PE_sdata4;
440
        break;
441
      case 8:
442
        encoding |= DW_EH_PE_sdata8;
443
        break;
444
      }
445
  return encoding | DW_EH_PE_pcrel;
446
}
447
 
448
/* Called before calling _bfd_elf_parse_eh_frame on every input bfd's
449
   .eh_frame section.  */
450
 
451
void
452
_bfd_elf_begin_eh_frame_parsing (struct bfd_link_info *info)
453
{
454
  struct eh_frame_hdr_info *hdr_info;
455
 
456
  hdr_info = &elf_hash_table (info)->eh_info;
457
  hdr_info->merge_cies = !info->relocatable;
458
}
459
 
460
/* Try to parse .eh_frame section SEC, which belongs to ABFD.  Store the
461
   information in the section's sec_info field on success.  COOKIE
462
   describes the relocations in SEC.  */
463
 
464
void
465
_bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
466
                         asection *sec, struct elf_reloc_cookie *cookie)
467
{
468
#define REQUIRE(COND)                                   \
469
  do                                                    \
470
    if (!(COND))                                        \
471
      goto free_no_table;                               \
472
  while (0)
473
 
474
  bfd_byte *ehbuf = NULL, *buf, *end;
475
  bfd_byte *last_fde;
476
  struct eh_cie_fde *this_inf;
477
  unsigned int hdr_length, hdr_id;
478
  unsigned int cie_count;
479
  struct cie *cie, *local_cies = NULL;
480
  struct elf_link_hash_table *htab;
481
  struct eh_frame_hdr_info *hdr_info;
482
  struct eh_frame_sec_info *sec_info = NULL;
483
  unsigned int ptr_size;
484
  unsigned int num_cies;
485
  unsigned int num_entries;
486
  elf_gc_mark_hook_fn gc_mark_hook;
487
 
488
  htab = elf_hash_table (info);
489
  hdr_info = &htab->eh_info;
490
  if (hdr_info->parsed_eh_frames)
491
    return;
492
 
493 161 khays
  if (sec->size == 0
494
      || sec->sec_info_type != ELF_INFO_TYPE_NONE)
495 14 khays
    {
496
      /* This file does not contain .eh_frame information.  */
497
      return;
498
    }
499
 
500
  if (bfd_is_abs_section (sec->output_section))
501
    {
502
      /* At least one of the sections is being discarded from the
503
         link, so we should just ignore them.  */
504
      return;
505
    }
506
 
507
  /* Read the frame unwind information from abfd.  */
508
 
509
  REQUIRE (bfd_malloc_and_get_section (abfd, sec, &ehbuf));
510
 
511
  if (sec->size >= 4
512
      && bfd_get_32 (abfd, ehbuf) == 0
513
      && cookie->rel == cookie->relend)
514
    {
515
      /* Empty .eh_frame section.  */
516
      free (ehbuf);
517
      return;
518
    }
519
 
520
  /* If .eh_frame section size doesn't fit into int, we cannot handle
521
     it (it would need to use 64-bit .eh_frame format anyway).  */
522
  REQUIRE (sec->size == (unsigned int) sec->size);
523
 
524
  ptr_size = (get_elf_backend_data (abfd)
525
              ->elf_backend_eh_frame_address_size (abfd, sec));
526
  REQUIRE (ptr_size != 0);
527
 
528
  /* Go through the section contents and work out how many FDEs and
529
     CIEs there are.  */
530
  buf = ehbuf;
531
  end = ehbuf + sec->size;
532
  num_cies = 0;
533
  num_entries = 0;
534
  while (buf != end)
535
    {
536
      num_entries++;
537
 
538
      /* Read the length of the entry.  */
539
      REQUIRE (skip_bytes (&buf, end, 4));
540
      hdr_length = bfd_get_32 (abfd, buf - 4);
541
 
542
      /* 64-bit .eh_frame is not supported.  */
543
      REQUIRE (hdr_length != 0xffffffff);
544
      if (hdr_length == 0)
545
        break;
546
 
547
      REQUIRE (skip_bytes (&buf, end, 4));
548
      hdr_id = bfd_get_32 (abfd, buf - 4);
549
      if (hdr_id == 0)
550
        num_cies++;
551
 
552
      REQUIRE (skip_bytes (&buf, end, hdr_length - 4));
553
    }
554
 
555
  sec_info = (struct eh_frame_sec_info *)
556
      bfd_zmalloc (sizeof (struct eh_frame_sec_info)
557
                   + (num_entries - 1) * sizeof (struct eh_cie_fde));
558
  REQUIRE (sec_info);
559
 
560
  /* We need to have a "struct cie" for each CIE in this section.  */
561
  local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies));
562
  REQUIRE (local_cies);
563
 
564
  /* FIXME: octets_per_byte.  */
565
#define ENSURE_NO_RELOCS(buf)                           \
566
  REQUIRE (!(cookie->rel < cookie->relend               \
567
             && (cookie->rel->r_offset                  \
568
                 < (bfd_size_type) ((buf) - ehbuf))     \
569
             && cookie->rel->r_info != 0))
570
 
571
  /* FIXME: octets_per_byte.  */
572
#define SKIP_RELOCS(buf)                                \
573
  while (cookie->rel < cookie->relend                   \
574
         && (cookie->rel->r_offset                      \
575
             < (bfd_size_type) ((buf) - ehbuf)))        \
576
    cookie->rel++
577
 
578
  /* FIXME: octets_per_byte.  */
579
#define GET_RELOC(buf)                                  \
580
  ((cookie->rel < cookie->relend                        \
581
    && (cookie->rel->r_offset                           \
582
        == (bfd_size_type) ((buf) - ehbuf)))            \
583
   ? cookie->rel : NULL)
584
 
585
  buf = ehbuf;
586
  cie_count = 0;
587
  gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
588
  while ((bfd_size_type) (buf - ehbuf) != sec->size)
589
    {
590
      char *aug;
591
      bfd_byte *start, *insns, *insns_end;
592
      bfd_size_type length;
593
      unsigned int set_loc_count;
594
 
595
      this_inf = sec_info->entry + sec_info->count;
596
      last_fde = buf;
597
 
598
      /* Read the length of the entry.  */
599
      REQUIRE (skip_bytes (&buf, ehbuf + sec->size, 4));
600
      hdr_length = bfd_get_32 (abfd, buf - 4);
601
 
602
      /* The CIE/FDE must be fully contained in this input section.  */
603
      REQUIRE ((bfd_size_type) (buf - ehbuf) + hdr_length <= sec->size);
604
      end = buf + hdr_length;
605
 
606
      this_inf->offset = last_fde - ehbuf;
607
      this_inf->size = 4 + hdr_length;
608
      this_inf->reloc_index = cookie->rel - cookie->rels;
609
 
610
      if (hdr_length == 0)
611
        {
612
          /* A zero-length CIE should only be found at the end of
613
             the section.  */
614
          REQUIRE ((bfd_size_type) (buf - ehbuf) == sec->size);
615
          ENSURE_NO_RELOCS (buf);
616
          sec_info->count++;
617
          break;
618
        }
619
 
620
      REQUIRE (skip_bytes (&buf, end, 4));
621
      hdr_id = bfd_get_32 (abfd, buf - 4);
622
 
623
      if (hdr_id == 0)
624
        {
625
          unsigned int initial_insn_length;
626
 
627
          /* CIE  */
628
          this_inf->cie = 1;
629
 
630
          /* Point CIE to one of the section-local cie structures.  */
631
          cie = local_cies + cie_count++;
632
 
633
          cie->cie_inf = this_inf;
634
          cie->length = hdr_length;
635
          cie->output_sec = sec->output_section;
636
          start = buf;
637
          REQUIRE (read_byte (&buf, end, &cie->version));
638
 
639
          /* Cannot handle unknown versions.  */
640
          REQUIRE (cie->version == 1
641
                   || cie->version == 3
642
                   || cie->version == 4);
643
          REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation));
644
 
645
          strcpy (cie->augmentation, (char *) buf);
646
          buf = (bfd_byte *) strchr ((char *) buf, '\0') + 1;
647
          ENSURE_NO_RELOCS (buf);
648
          if (buf[0] == 'e' && buf[1] == 'h')
649
            {
650
              /* GCC < 3.0 .eh_frame CIE */
651
              /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
652
                 is private to each CIE, so we don't need it for anything.
653
                 Just skip it.  */
654
              REQUIRE (skip_bytes (&buf, end, ptr_size));
655
              SKIP_RELOCS (buf);
656
            }
657
          if (cie->version >= 4)
658
            {
659
              REQUIRE (buf + 1 < end);
660
              REQUIRE (buf[0] == ptr_size);
661
              REQUIRE (buf[1] == 0);
662
              buf += 2;
663
            }
664
          REQUIRE (read_uleb128 (&buf, end, &cie->code_align));
665
          REQUIRE (read_sleb128 (&buf, end, &cie->data_align));
666
          if (cie->version == 1)
667
            {
668
              REQUIRE (buf < end);
669
              cie->ra_column = *buf++;
670
            }
671
          else
672
            REQUIRE (read_uleb128 (&buf, end, &cie->ra_column));
673
          ENSURE_NO_RELOCS (buf);
674
          cie->lsda_encoding = DW_EH_PE_omit;
675
          cie->fde_encoding = DW_EH_PE_omit;
676
          cie->per_encoding = DW_EH_PE_omit;
677
          aug = cie->augmentation;
678
          if (aug[0] != 'e' || aug[1] != 'h')
679
            {
680
              if (*aug == 'z')
681
                {
682
                  aug++;
683
                  REQUIRE (read_uleb128 (&buf, end, &cie->augmentation_size));
684
                  ENSURE_NO_RELOCS (buf);
685
                }
686
 
687
              while (*aug != '\0')
688
                switch (*aug++)
689
                  {
690
                  case 'L':
691
                    REQUIRE (read_byte (&buf, end, &cie->lsda_encoding));
692
                    ENSURE_NO_RELOCS (buf);
693
                    REQUIRE (get_DW_EH_PE_width (cie->lsda_encoding, ptr_size));
694
                    break;
695
                  case 'R':
696
                    REQUIRE (read_byte (&buf, end, &cie->fde_encoding));
697
                    ENSURE_NO_RELOCS (buf);
698
                    REQUIRE (get_DW_EH_PE_width (cie->fde_encoding, ptr_size));
699
                    break;
700
                  case 'S':
701
                    break;
702
                  case 'P':
703
                    {
704
                      int per_width;
705
 
706
                      REQUIRE (read_byte (&buf, end, &cie->per_encoding));
707
                      per_width = get_DW_EH_PE_width (cie->per_encoding,
708
                                                      ptr_size);
709
                      REQUIRE (per_width);
710
                      if ((cie->per_encoding & 0x70) == DW_EH_PE_aligned)
711
                        {
712
                          length = -(buf - ehbuf) & (per_width - 1);
713
                          REQUIRE (skip_bytes (&buf, end, length));
714
                        }
715
                      this_inf->u.cie.personality_offset = buf - start;
716
                      ENSURE_NO_RELOCS (buf);
717
                      /* Ensure we have a reloc here.  */
718
                      REQUIRE (GET_RELOC (buf));
719
                      cie->personality.reloc_index
720
                        = cookie->rel - cookie->rels;
721
                      /* Cope with MIPS-style composite relocations.  */
722
                      do
723
                        cookie->rel++;
724
                      while (GET_RELOC (buf) != NULL);
725
                      REQUIRE (skip_bytes (&buf, end, per_width));
726
                    }
727
                    break;
728
                  default:
729
                    /* Unrecognized augmentation. Better bail out.  */
730
                    goto free_no_table;
731
                  }
732
            }
733
 
734
          /* For shared libraries, try to get rid of as many RELATIVE relocs
735
             as possible.  */
736
          if (info->shared
737
              && (get_elf_backend_data (abfd)
738
                  ->elf_backend_can_make_relative_eh_frame
739
                  (abfd, info, sec)))
740
            {
741
              if ((cie->fde_encoding & 0x70) == DW_EH_PE_absptr)
742
                this_inf->make_relative = 1;
743
              /* If the CIE doesn't already have an 'R' entry, it's fairly
744
                 easy to add one, provided that there's no aligned data
745
                 after the augmentation string.  */
746
              else if (cie->fde_encoding == DW_EH_PE_omit
747
                       && (cie->per_encoding & 0x70) != DW_EH_PE_aligned)
748
                {
749
                  if (*cie->augmentation == 0)
750
                    this_inf->add_augmentation_size = 1;
751
                  this_inf->u.cie.add_fde_encoding = 1;
752
                  this_inf->make_relative = 1;
753
                }
754
 
755
              if ((cie->lsda_encoding & 0x70) == DW_EH_PE_absptr)
756
                cie->can_make_lsda_relative = 1;
757
            }
758
 
759
          /* If FDE encoding was not specified, it defaults to
760
             DW_EH_absptr.  */
761
          if (cie->fde_encoding == DW_EH_PE_omit)
762
            cie->fde_encoding = DW_EH_PE_absptr;
763
 
764
          initial_insn_length = end - buf;
765
          if (initial_insn_length <= sizeof (cie->initial_instructions))
766
            {
767
              cie->initial_insn_length = initial_insn_length;
768
              memcpy (cie->initial_instructions, buf, initial_insn_length);
769
            }
770
          insns = buf;
771
          buf += initial_insn_length;
772
          ENSURE_NO_RELOCS (buf);
773
 
774
          if (hdr_info->merge_cies)
775
            this_inf->u.cie.u.full_cie = cie;
776
          this_inf->u.cie.per_encoding_relative
777
            = (cie->per_encoding & 0x70) == DW_EH_PE_pcrel;
778
        }
779
      else
780
        {
781
          /* Find the corresponding CIE.  */
782
          unsigned int cie_offset = this_inf->offset + 4 - hdr_id;
783
          for (cie = local_cies; cie < local_cies + cie_count; cie++)
784
            if (cie_offset == cie->cie_inf->offset)
785
              break;
786
 
787
          /* Ensure this FDE references one of the CIEs in this input
788
             section.  */
789
          REQUIRE (cie != local_cies + cie_count);
790
          this_inf->u.fde.cie_inf = cie->cie_inf;
791
          this_inf->make_relative = cie->cie_inf->make_relative;
792
          this_inf->add_augmentation_size
793
            = cie->cie_inf->add_augmentation_size;
794
 
795
          ENSURE_NO_RELOCS (buf);
796 161 khays
          if ((sec->flags & SEC_LINKER_CREATED) == 0 || cookie->rels != NULL)
797
            {
798
              asection *rsec;
799 14 khays
 
800 161 khays
              REQUIRE (GET_RELOC (buf));
801
 
802
              /* Chain together the FDEs for each section.  */
803
              rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie);
804
              /* RSEC will be NULL if FDE was cleared out as it was belonging to
805
                 a discarded SHT_GROUP.  */
806
              if (rsec)
807
                {
808
                  REQUIRE (rsec->owner == abfd);
809
                  this_inf->u.fde.next_for_section = elf_fde_list (rsec);
810
                  elf_fde_list (rsec) = this_inf;
811
                }
812 14 khays
            }
813
 
814
          /* Skip the initial location and address range.  */
815
          start = buf;
816
          length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
817
          REQUIRE (skip_bytes (&buf, end, 2 * length));
818
 
819
          /* Skip the augmentation size, if present.  */
820
          if (cie->augmentation[0] == 'z')
821
            REQUIRE (read_uleb128 (&buf, end, &length));
822
          else
823
            length = 0;
824
 
825
          /* Of the supported augmentation characters above, only 'L'
826
             adds augmentation data to the FDE.  This code would need to
827
             be adjusted if any future augmentations do the same thing.  */
828
          if (cie->lsda_encoding != DW_EH_PE_omit)
829
            {
830
              SKIP_RELOCS (buf);
831
              if (cie->can_make_lsda_relative && GET_RELOC (buf))
832
                cie->cie_inf->u.cie.make_lsda_relative = 1;
833
              this_inf->lsda_offset = buf - start;
834
              /* If there's no 'z' augmentation, we don't know where the
835
                 CFA insns begin.  Assume no padding.  */
836
              if (cie->augmentation[0] != 'z')
837
                length = end - buf;
838
            }
839
 
840
          /* Skip over the augmentation data.  */
841
          REQUIRE (skip_bytes (&buf, end, length));
842
          insns = buf;
843
 
844
          buf = last_fde + 4 + hdr_length;
845
 
846
          /* For NULL RSEC (cleared FDE belonging to a discarded section)
847
             the relocations are commonly cleared.  We do not sanity check if
848
             all these relocations are cleared as (1) relocations to
849
             .gcc_except_table will remain uncleared (they will get dropped
850
             with the drop of this unused FDE) and (2) BFD already safely drops
851
             relocations of any type to .eh_frame by
852
             elf_section_ignore_discarded_relocs.
853
             TODO: The .gcc_except_table entries should be also filtered as
854
             .eh_frame entries; or GCC could rather use COMDAT for them.  */
855
          SKIP_RELOCS (buf);
856
        }
857
 
858
      /* Try to interpret the CFA instructions and find the first
859
         padding nop.  Shrink this_inf's size so that it doesn't
860
         include the padding.  */
861
      length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
862
      set_loc_count = 0;
863
      insns_end = skip_non_nops (insns, end, length, &set_loc_count);
864
      /* If we don't understand the CFA instructions, we can't know
865
         what needs to be adjusted there.  */
866
      if (insns_end == NULL
867
          /* For the time being we don't support DW_CFA_set_loc in
868
             CIE instructions.  */
869
          || (set_loc_count && this_inf->cie))
870
        goto free_no_table;
871
      this_inf->size -= end - insns_end;
872
      if (insns_end != end && this_inf->cie)
873
        {
874
          cie->initial_insn_length -= end - insns_end;
875
          cie->length -= end - insns_end;
876
        }
877
      if (set_loc_count
878
          && ((cie->fde_encoding & 0x70) == DW_EH_PE_pcrel
879
              || this_inf->make_relative))
880
        {
881
          unsigned int cnt;
882
          bfd_byte *p;
883
 
884
          this_inf->set_loc = (unsigned int *)
885
              bfd_malloc ((set_loc_count + 1) * sizeof (unsigned int));
886
          REQUIRE (this_inf->set_loc);
887
          this_inf->set_loc[0] = set_loc_count;
888
          p = insns;
889
          cnt = 0;
890
          while (p < end)
891
            {
892
              if (*p == DW_CFA_set_loc)
893
                this_inf->set_loc[++cnt] = p + 1 - start;
894
              REQUIRE (skip_cfa_op (&p, end, length));
895
            }
896
        }
897
 
898
      this_inf->removed = 1;
899
      this_inf->fde_encoding = cie->fde_encoding;
900
      this_inf->lsda_encoding = cie->lsda_encoding;
901
      sec_info->count++;
902
    }
903
  BFD_ASSERT (sec_info->count == num_entries);
904
  BFD_ASSERT (cie_count == num_cies);
905
 
906
  elf_section_data (sec)->sec_info = sec_info;
907
  sec->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
908
  if (hdr_info->merge_cies)
909
    {
910
      sec_info->cies = local_cies;
911
      local_cies = NULL;
912
    }
913
  goto success;
914
 
915
 free_no_table:
916
  (*info->callbacks->einfo)
917
    (_("%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"),
918
     abfd, sec);
919
  hdr_info->table = FALSE;
920
  if (sec_info)
921
    free (sec_info);
922
 success:
923
  if (ehbuf)
924
    free (ehbuf);
925
  if (local_cies)
926
    free (local_cies);
927
#undef REQUIRE
928
}
929
 
930
/* Finish a pass over all .eh_frame sections.  */
931
 
932
void
933
_bfd_elf_end_eh_frame_parsing (struct bfd_link_info *info)
934
{
935
  struct eh_frame_hdr_info *hdr_info;
936
 
937
  hdr_info = &elf_hash_table (info)->eh_info;
938
  hdr_info->parsed_eh_frames = TRUE;
939
}
940
 
941
/* Mark all relocations against CIE or FDE ENT, which occurs in
942
   .eh_frame section SEC.  COOKIE describes the relocations in SEC;
943
   its "rel" field can be changed freely.  */
944
 
945
static bfd_boolean
946
mark_entry (struct bfd_link_info *info, asection *sec,
947
            struct eh_cie_fde *ent, elf_gc_mark_hook_fn gc_mark_hook,
948
            struct elf_reloc_cookie *cookie)
949
{
950
  /* FIXME: octets_per_byte.  */
951
  for (cookie->rel = cookie->rels + ent->reloc_index;
952
       cookie->rel < cookie->relend
953
         && cookie->rel->r_offset < ent->offset + ent->size;
954
       cookie->rel++)
955
    if (!_bfd_elf_gc_mark_reloc (info, sec, gc_mark_hook, cookie))
956
      return FALSE;
957
 
958
  return TRUE;
959
}
960
 
961
/* Mark all the relocations against FDEs that relate to code in input
962
   section SEC.  The FDEs belong to .eh_frame section EH_FRAME, whose
963
   relocations are described by COOKIE.  */
964
 
965
bfd_boolean
966
_bfd_elf_gc_mark_fdes (struct bfd_link_info *info, asection *sec,
967
                       asection *eh_frame, elf_gc_mark_hook_fn gc_mark_hook,
968
                       struct elf_reloc_cookie *cookie)
969
{
970
  struct eh_cie_fde *fde, *cie;
971
 
972
  for (fde = elf_fde_list (sec); fde; fde = fde->u.fde.next_for_section)
973
    {
974
      if (!mark_entry (info, eh_frame, fde, gc_mark_hook, cookie))
975
        return FALSE;
976
 
977
      /* At this stage, all cie_inf fields point to local CIEs, so we
978
         can use the same cookie to refer to them.  */
979
      cie = fde->u.fde.cie_inf;
980
      if (!cie->u.cie.gc_mark)
981
        {
982
          cie->u.cie.gc_mark = 1;
983
          if (!mark_entry (info, eh_frame, cie, gc_mark_hook, cookie))
984
            return FALSE;
985
        }
986
    }
987
  return TRUE;
988
}
989
 
990
/* Input section SEC of ABFD is an .eh_frame section that contains the
991
   CIE described by CIE_INF.  Return a version of CIE_INF that is going
992
   to be kept in the output, adding CIE_INF to the output if necessary.
993
 
994
   HDR_INFO is the .eh_frame_hdr information and COOKIE describes the
995
   relocations in REL.  */
996
 
997
static struct eh_cie_fde *
998
find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec,
999
                 struct eh_frame_hdr_info *hdr_info,
1000
                 struct elf_reloc_cookie *cookie,
1001
                 struct eh_cie_fde *cie_inf)
1002
{
1003
  unsigned long r_symndx;
1004
  struct cie *cie, *new_cie;
1005
  Elf_Internal_Rela *rel;
1006
  void **loc;
1007
 
1008
  /* Use CIE_INF if we have already decided to keep it.  */
1009
  if (!cie_inf->removed)
1010
    return cie_inf;
1011
 
1012
  /* If we have merged CIE_INF with another CIE, use that CIE instead.  */
1013
  if (cie_inf->u.cie.merged)
1014
    return cie_inf->u.cie.u.merged_with;
1015
 
1016
  cie = cie_inf->u.cie.u.full_cie;
1017
 
1018
  /* Assume we will need to keep CIE_INF.  */
1019
  cie_inf->removed = 0;
1020
  cie_inf->u.cie.u.sec = sec;
1021
 
1022
  /* If we are not merging CIEs, use CIE_INF.  */
1023
  if (cie == NULL)
1024
    return cie_inf;
1025
 
1026
  if (cie->per_encoding != DW_EH_PE_omit)
1027
    {
1028
      bfd_boolean per_binds_local;
1029
 
1030
      /* Work out the address of personality routine, either as an absolute
1031
         value or as a symbol.  */
1032
      rel = cookie->rels + cie->personality.reloc_index;
1033
      memset (&cie->personality, 0, sizeof (cie->personality));
1034
#ifdef BFD64
1035
      if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
1036
        r_symndx = ELF64_R_SYM (rel->r_info);
1037
      else
1038
#endif
1039
        r_symndx = ELF32_R_SYM (rel->r_info);
1040
      if (r_symndx >= cookie->locsymcount
1041
          || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
1042
        {
1043
          struct elf_link_hash_entry *h;
1044
 
1045
          r_symndx -= cookie->extsymoff;
1046
          h = cookie->sym_hashes[r_symndx];
1047
 
1048
          while (h->root.type == bfd_link_hash_indirect
1049
                 || h->root.type == bfd_link_hash_warning)
1050
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
1051
 
1052
          cie->personality.h = h;
1053
          per_binds_local = SYMBOL_REFERENCES_LOCAL (info, h);
1054
        }
1055
      else
1056
        {
1057
          Elf_Internal_Sym *sym;
1058
          asection *sym_sec;
1059
 
1060
          sym = &cookie->locsyms[r_symndx];
1061
          sym_sec = bfd_section_from_elf_index (abfd, sym->st_shndx);
1062
          if (sym_sec == NULL)
1063
            return cie_inf;
1064
 
1065
          if (sym_sec->kept_section != NULL)
1066
            sym_sec = sym_sec->kept_section;
1067
          if (sym_sec->output_section == NULL)
1068
            return cie_inf;
1069
 
1070
          cie->local_personality = 1;
1071
          cie->personality.val = (sym->st_value
1072
                                  + sym_sec->output_offset
1073
                                  + sym_sec->output_section->vma);
1074
          per_binds_local = TRUE;
1075
        }
1076
 
1077
      if (per_binds_local
1078
          && info->shared
1079
          && (cie->per_encoding & 0x70) == DW_EH_PE_absptr
1080
          && (get_elf_backend_data (abfd)
1081
              ->elf_backend_can_make_relative_eh_frame (abfd, info, sec)))
1082
        {
1083
          cie_inf->u.cie.make_per_encoding_relative = 1;
1084
          cie_inf->u.cie.per_encoding_relative = 1;
1085
        }
1086
    }
1087
 
1088
  /* See if we can merge this CIE with an earlier one.  */
1089
  cie->output_sec = sec->output_section;
1090
  cie_compute_hash (cie);
1091
  if (hdr_info->cies == NULL)
1092
    {
1093
      hdr_info->cies = htab_try_create (1, cie_hash, cie_eq, free);
1094
      if (hdr_info->cies == NULL)
1095
        return cie_inf;
1096
    }
1097
  loc = htab_find_slot_with_hash (hdr_info->cies, cie, cie->hash, INSERT);
1098
  if (loc == NULL)
1099
    return cie_inf;
1100
 
1101
  new_cie = (struct cie *) *loc;
1102
  if (new_cie == NULL)
1103
    {
1104
      /* Keep CIE_INF and record it in the hash table.  */
1105
      new_cie = (struct cie *) malloc (sizeof (struct cie));
1106
      if (new_cie == NULL)
1107
        return cie_inf;
1108
 
1109
      memcpy (new_cie, cie, sizeof (struct cie));
1110
      *loc = new_cie;
1111
    }
1112
  else
1113
    {
1114
      /* Merge CIE_INF with NEW_CIE->CIE_INF.  */
1115
      cie_inf->removed = 1;
1116
      cie_inf->u.cie.merged = 1;
1117
      cie_inf->u.cie.u.merged_with = new_cie->cie_inf;
1118
      if (cie_inf->u.cie.make_lsda_relative)
1119
        new_cie->cie_inf->u.cie.make_lsda_relative = 1;
1120
    }
1121
  return new_cie->cie_inf;
1122
}
1123
 
1124
/* This function is called for each input file before the .eh_frame
1125
   section is relocated.  It discards duplicate CIEs and FDEs for discarded
1126
   functions.  The function returns TRUE iff any entries have been
1127
   deleted.  */
1128
 
1129
bfd_boolean
1130
_bfd_elf_discard_section_eh_frame
1131
   (bfd *abfd, struct bfd_link_info *info, asection *sec,
1132
    bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *),
1133
    struct elf_reloc_cookie *cookie)
1134
{
1135
  struct eh_cie_fde *ent;
1136
  struct eh_frame_sec_info *sec_info;
1137
  struct eh_frame_hdr_info *hdr_info;
1138
  unsigned int ptr_size, offset;
1139
 
1140 161 khays
  if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
1141
    return FALSE;
1142
 
1143 14 khays
  sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
1144
  if (sec_info == NULL)
1145
    return FALSE;
1146
 
1147 161 khays
  ptr_size = (get_elf_backend_data (sec->owner)
1148
              ->elf_backend_eh_frame_address_size (sec->owner, sec));
1149
 
1150 14 khays
  hdr_info = &elf_hash_table (info)->eh_info;
1151
  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
1152
    if (ent->size == 4)
1153
      /* There should only be one zero terminator, on the last input
1154
         file supplying .eh_frame (crtend.o).  Remove any others.  */
1155
      ent->removed = sec->map_head.s != NULL;
1156
    else if (!ent->cie)
1157
      {
1158 161 khays
        bfd_boolean keep;
1159
        if ((sec->flags & SEC_LINKER_CREATED) != 0 && cookie->rels == NULL)
1160 14 khays
          {
1161 161 khays
            unsigned int width
1162
              = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
1163
            bfd_vma value
1164
              = read_value (abfd, sec->contents + ent->offset + 8 + width,
1165
                            width, get_DW_EH_PE_signed (ent->fde_encoding));
1166
            keep = value != 0;
1167
          }
1168
        else
1169
          {
1170
            cookie->rel = cookie->rels + ent->reloc_index;
1171
            /* FIXME: octets_per_byte.  */
1172
            BFD_ASSERT (cookie->rel < cookie->relend
1173
                        && cookie->rel->r_offset == ent->offset + 8);
1174
            keep = !(*reloc_symbol_deleted_p) (ent->offset + 8, cookie);
1175
          }
1176
        if (keep)
1177
          {
1178 14 khays
            if (info->shared
1179
                && (((ent->fde_encoding & 0x70) == DW_EH_PE_absptr
1180
                     && ent->make_relative == 0)
1181
                    || (ent->fde_encoding & 0x70) == DW_EH_PE_aligned))
1182
              {
1183
                /* If a shared library uses absolute pointers
1184
                   which we cannot turn into PC relative,
1185
                   don't create the binary search table,
1186
                   since it is affected by runtime relocations.  */
1187
                hdr_info->table = FALSE;
1188
                (*info->callbacks->einfo)
1189
                  (_("%P: fde encoding in %B(%A) prevents .eh_frame_hdr"
1190
                     " table being created.\n"), abfd, sec);
1191
              }
1192
            ent->removed = 0;
1193
            hdr_info->fde_count++;
1194
            ent->u.fde.cie_inf = find_merged_cie (abfd, info, sec, hdr_info,
1195
                                                  cookie, ent->u.fde.cie_inf);
1196
          }
1197
      }
1198
 
1199
  if (sec_info->cies)
1200
    {
1201
      free (sec_info->cies);
1202
      sec_info->cies = NULL;
1203
    }
1204
 
1205
  offset = 0;
1206
  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
1207
    if (!ent->removed)
1208
      {
1209
        ent->new_offset = offset;
1210
        offset += size_of_output_cie_fde (ent, ptr_size);
1211
      }
1212
 
1213
  sec->rawsize = sec->size;
1214
  sec->size = offset;
1215
  return offset != sec->rawsize;
1216
}
1217
 
1218
/* This function is called for .eh_frame_hdr section after
1219
   _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
1220
   input sections.  It finalizes the size of .eh_frame_hdr section.  */
1221
 
1222
bfd_boolean
1223
_bfd_elf_discard_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
1224
{
1225
  struct elf_link_hash_table *htab;
1226
  struct eh_frame_hdr_info *hdr_info;
1227
  asection *sec;
1228
 
1229
  htab = elf_hash_table (info);
1230
  hdr_info = &htab->eh_info;
1231
 
1232
  if (hdr_info->cies != NULL)
1233
    {
1234
      htab_delete (hdr_info->cies);
1235
      hdr_info->cies = NULL;
1236
    }
1237
 
1238
  sec = hdr_info->hdr_sec;
1239
  if (sec == NULL)
1240
    return FALSE;
1241
 
1242
  sec->size = EH_FRAME_HDR_SIZE;
1243
  if (hdr_info->table)
1244
    sec->size += 4 + hdr_info->fde_count * 8;
1245
 
1246
  elf_tdata (abfd)->eh_frame_hdr = sec;
1247
  return TRUE;
1248
}
1249
 
1250
/* This function is called from size_dynamic_sections.
1251
   It needs to decide whether .eh_frame_hdr should be output or not,
1252
   because when the dynamic symbol table has been sized it is too late
1253
   to strip sections.  */
1254
 
1255
bfd_boolean
1256
_bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info)
1257
{
1258
  asection *o;
1259
  bfd *abfd;
1260
  struct elf_link_hash_table *htab;
1261
  struct eh_frame_hdr_info *hdr_info;
1262
 
1263
  htab = elf_hash_table (info);
1264
  hdr_info = &htab->eh_info;
1265
  if (hdr_info->hdr_sec == NULL)
1266
    return TRUE;
1267
 
1268
  if (bfd_is_abs_section (hdr_info->hdr_sec->output_section))
1269
    {
1270
      hdr_info->hdr_sec = NULL;
1271
      return TRUE;
1272
    }
1273
 
1274
  abfd = NULL;
1275
  if (info->eh_frame_hdr)
1276
    for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
1277
      {
1278
        /* Count only sections which have at least a single CIE or FDE.
1279
           There cannot be any CIE or FDE <= 8 bytes.  */
1280
        o = bfd_get_section_by_name (abfd, ".eh_frame");
1281
        if (o && o->size > 8 && !bfd_is_abs_section (o->output_section))
1282
          break;
1283
      }
1284
 
1285
  if (abfd == NULL)
1286
    {
1287
      hdr_info->hdr_sec->flags |= SEC_EXCLUDE;
1288
      hdr_info->hdr_sec = NULL;
1289
      return TRUE;
1290
    }
1291
 
1292
  hdr_info->table = TRUE;
1293
  return TRUE;
1294
}
1295
 
1296
/* Adjust an address in the .eh_frame section.  Given OFFSET within
1297
   SEC, this returns the new offset in the adjusted .eh_frame section,
1298
   or -1 if the address refers to a CIE/FDE which has been removed
1299
   or to offset with dynamic relocation which is no longer needed.  */
1300
 
1301
bfd_vma
1302
_bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
1303
                                  struct bfd_link_info *info ATTRIBUTE_UNUSED,
1304
                                  asection *sec,
1305
                                  bfd_vma offset)
1306
{
1307
  struct eh_frame_sec_info *sec_info;
1308
  unsigned int lo, hi, mid;
1309
 
1310
  if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
1311
    return offset;
1312
  sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
1313
 
1314
  if (offset >= sec->rawsize)
1315
    return offset - sec->rawsize + sec->size;
1316
 
1317
  lo = 0;
1318
  hi = sec_info->count;
1319
  mid = 0;
1320
  while (lo < hi)
1321
    {
1322
      mid = (lo + hi) / 2;
1323
      if (offset < sec_info->entry[mid].offset)
1324
        hi = mid;
1325
      else if (offset
1326
               >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
1327
        lo = mid + 1;
1328
      else
1329
        break;
1330
    }
1331
 
1332
  BFD_ASSERT (lo < hi);
1333
 
1334
  /* FDE or CIE was removed.  */
1335
  if (sec_info->entry[mid].removed)
1336
    return (bfd_vma) -1;
1337
 
1338
  /* If converting personality pointers to DW_EH_PE_pcrel, there will be
1339
     no need for run-time relocation against the personality field.  */
1340
  if (sec_info->entry[mid].cie
1341
      && sec_info->entry[mid].u.cie.make_per_encoding_relative
1342
      && offset == (sec_info->entry[mid].offset + 8
1343
                    + sec_info->entry[mid].u.cie.personality_offset))
1344
    return (bfd_vma) -2;
1345
 
1346
  /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
1347
     relocation against FDE's initial_location field.  */
1348
  if (!sec_info->entry[mid].cie
1349
      && sec_info->entry[mid].make_relative
1350
      && offset == sec_info->entry[mid].offset + 8)
1351
    return (bfd_vma) -2;
1352
 
1353
  /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
1354
     for run-time relocation against LSDA field.  */
1355
  if (!sec_info->entry[mid].cie
1356
      && sec_info->entry[mid].u.fde.cie_inf->u.cie.make_lsda_relative
1357
      && offset == (sec_info->entry[mid].offset + 8
1358
                    + sec_info->entry[mid].lsda_offset))
1359
    return (bfd_vma) -2;
1360
 
1361
  /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
1362
     relocation against DW_CFA_set_loc's arguments.  */
1363
  if (sec_info->entry[mid].set_loc
1364
      && sec_info->entry[mid].make_relative
1365
      && (offset >= sec_info->entry[mid].offset + 8
1366
                    + sec_info->entry[mid].set_loc[1]))
1367
    {
1368
      unsigned int cnt;
1369
 
1370
      for (cnt = 1; cnt <= sec_info->entry[mid].set_loc[0]; cnt++)
1371
        if (offset == sec_info->entry[mid].offset + 8
1372
                      + sec_info->entry[mid].set_loc[cnt])
1373
          return (bfd_vma) -2;
1374
    }
1375
 
1376
  /* Any new augmentation bytes go before the first relocation.  */
1377
  return (offset + sec_info->entry[mid].new_offset
1378
          - sec_info->entry[mid].offset
1379
          + extra_augmentation_string_bytes (sec_info->entry + mid)
1380
          + extra_augmentation_data_bytes (sec_info->entry + mid));
1381
}
1382
 
1383
/* Write out .eh_frame section.  This is called with the relocated
1384
   contents.  */
1385
 
1386
bfd_boolean
1387
_bfd_elf_write_section_eh_frame (bfd *abfd,
1388
                                 struct bfd_link_info *info,
1389
                                 asection *sec,
1390
                                 bfd_byte *contents)
1391
{
1392
  struct eh_frame_sec_info *sec_info;
1393
  struct elf_link_hash_table *htab;
1394
  struct eh_frame_hdr_info *hdr_info;
1395
  unsigned int ptr_size;
1396
  struct eh_cie_fde *ent;
1397
 
1398
  if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
1399
    /* FIXME: octets_per_byte.  */
1400
    return bfd_set_section_contents (abfd, sec->output_section, contents,
1401
                                     sec->output_offset, sec->size);
1402
 
1403
  ptr_size = (get_elf_backend_data (abfd)
1404
              ->elf_backend_eh_frame_address_size (abfd, sec));
1405
  BFD_ASSERT (ptr_size != 0);
1406
 
1407
  sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
1408
  htab = elf_hash_table (info);
1409
  hdr_info = &htab->eh_info;
1410
 
1411
  if (hdr_info->table && hdr_info->array == NULL)
1412
    hdr_info->array = (struct eh_frame_array_ent *)
1413
        bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
1414
  if (hdr_info->array == NULL)
1415
    hdr_info = NULL;
1416
 
1417
  /* The new offsets can be bigger or smaller than the original offsets.
1418
     We therefore need to make two passes over the section: one backward
1419
     pass to move entries up and one forward pass to move entries down.
1420
     The two passes won't interfere with each other because entries are
1421
     not reordered  */
1422
  for (ent = sec_info->entry + sec_info->count; ent-- != sec_info->entry;)
1423
    if (!ent->removed && ent->new_offset > ent->offset)
1424
      memmove (contents + ent->new_offset, contents + ent->offset, ent->size);
1425
 
1426
  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
1427
    if (!ent->removed && ent->new_offset < ent->offset)
1428
      memmove (contents + ent->new_offset, contents + ent->offset, ent->size);
1429
 
1430
  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
1431
    {
1432
      unsigned char *buf, *end;
1433
      unsigned int new_size;
1434
 
1435
      if (ent->removed)
1436
        continue;
1437
 
1438
      if (ent->size == 4)
1439
        {
1440
          /* Any terminating FDE must be at the end of the section.  */
1441
          BFD_ASSERT (ent == sec_info->entry + sec_info->count - 1);
1442
          continue;
1443
        }
1444
 
1445
      buf = contents + ent->new_offset;
1446
      end = buf + ent->size;
1447
      new_size = size_of_output_cie_fde (ent, ptr_size);
1448
 
1449
      /* Update the size.  It may be shrinked.  */
1450
      bfd_put_32 (abfd, new_size - 4, buf);
1451
 
1452
      /* Filling the extra bytes with DW_CFA_nops.  */
1453
      if (new_size != ent->size)
1454
        memset (end, 0, new_size - ent->size);
1455
 
1456
      if (ent->cie)
1457
        {
1458
          /* CIE */
1459
          if (ent->make_relative
1460
              || ent->u.cie.make_lsda_relative
1461
              || ent->u.cie.per_encoding_relative)
1462
            {
1463
              char *aug;
1464
              unsigned int action, extra_string, extra_data;
1465
              unsigned int per_width, per_encoding;
1466
 
1467
              /* Need to find 'R' or 'L' augmentation's argument and modify
1468
                 DW_EH_PE_* value.  */
1469
              action = ((ent->make_relative ? 1 : 0)
1470
                        | (ent->u.cie.make_lsda_relative ? 2 : 0)
1471
                        | (ent->u.cie.per_encoding_relative ? 4 : 0));
1472
              extra_string = extra_augmentation_string_bytes (ent);
1473
              extra_data = extra_augmentation_data_bytes (ent);
1474
 
1475
              /* Skip length, id and version.  */
1476
              buf += 9;
1477
              aug = (char *) buf;
1478
              buf += strlen (aug) + 1;
1479
              skip_leb128 (&buf, end);
1480
              skip_leb128 (&buf, end);
1481
              skip_leb128 (&buf, end);
1482
              if (*aug == 'z')
1483
                {
1484
                  /* The uleb128 will always be a single byte for the kind
1485
                     of augmentation strings that we're prepared to handle.  */
1486
                  *buf++ += extra_data;
1487
                  aug++;
1488
                }
1489
 
1490
              /* Make room for the new augmentation string and data bytes.  */
1491
              memmove (buf + extra_string + extra_data, buf, end - buf);
1492
              memmove (aug + extra_string, aug, buf - (bfd_byte *) aug);
1493
              buf += extra_string;
1494
              end += extra_string + extra_data;
1495
 
1496
              if (ent->add_augmentation_size)
1497
                {
1498
                  *aug++ = 'z';
1499
                  *buf++ = extra_data - 1;
1500
                }
1501
              if (ent->u.cie.add_fde_encoding)
1502
                {
1503
                  BFD_ASSERT (action & 1);
1504
                  *aug++ = 'R';
1505
                  *buf++ = make_pc_relative (DW_EH_PE_absptr, ptr_size);
1506
                  action &= ~1;
1507
                }
1508
 
1509
              while (action)
1510
                switch (*aug++)
1511
                  {
1512
                  case 'L':
1513
                    if (action & 2)
1514
                      {
1515
                        BFD_ASSERT (*buf == ent->lsda_encoding);
1516
                        *buf = make_pc_relative (*buf, ptr_size);
1517
                        action &= ~2;
1518
                      }
1519
                    buf++;
1520
                    break;
1521
                  case 'P':
1522
                    if (ent->u.cie.make_per_encoding_relative)
1523
                      *buf = make_pc_relative (*buf, ptr_size);
1524
                    per_encoding = *buf++;
1525
                    per_width = get_DW_EH_PE_width (per_encoding, ptr_size);
1526
                    BFD_ASSERT (per_width != 0);
1527
                    BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
1528
                                == ent->u.cie.per_encoding_relative);
1529
                    if ((per_encoding & 0x70) == DW_EH_PE_aligned)
1530
                      buf = (contents
1531
                             + ((buf - contents + per_width - 1)
1532
                                & ~((bfd_size_type) per_width - 1)));
1533
                    if (action & 4)
1534
                      {
1535
                        bfd_vma val;
1536
 
1537
                        val = read_value (abfd, buf, per_width,
1538
                                          get_DW_EH_PE_signed (per_encoding));
1539
                        if (ent->u.cie.make_per_encoding_relative)
1540
                          val -= (sec->output_section->vma
1541
                                  + sec->output_offset
1542
                                  + (buf - contents));
1543
                        else
1544
                          {
1545
                            val += (bfd_vma) ent->offset - ent->new_offset;
1546
                            val -= extra_string + extra_data;
1547
                          }
1548
                        write_value (abfd, buf, val, per_width);
1549
                        action &= ~4;
1550
                      }
1551
                    buf += per_width;
1552
                    break;
1553
                  case 'R':
1554
                    if (action & 1)
1555
                      {
1556
                        BFD_ASSERT (*buf == ent->fde_encoding);
1557
                        *buf = make_pc_relative (*buf, ptr_size);
1558
                        action &= ~1;
1559
                      }
1560
                    buf++;
1561
                    break;
1562
                  case 'S':
1563
                    break;
1564
                  default:
1565
                    BFD_FAIL ();
1566
                  }
1567
            }
1568
        }
1569
      else
1570
        {
1571
          /* FDE */
1572
          bfd_vma value, address;
1573
          unsigned int width;
1574
          bfd_byte *start;
1575
          struct eh_cie_fde *cie;
1576
 
1577
          /* Skip length.  */
1578
          cie = ent->u.fde.cie_inf;
1579
          buf += 4;
1580
          value = ((ent->new_offset + sec->output_offset + 4)
1581
                   - (cie->new_offset + cie->u.cie.u.sec->output_offset));
1582
          bfd_put_32 (abfd, value, buf);
1583
          buf += 4;
1584
          width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
1585
          value = read_value (abfd, buf, width,
1586
                              get_DW_EH_PE_signed (ent->fde_encoding));
1587
          address = value;
1588
          if (value)
1589
            {
1590
              switch (ent->fde_encoding & 0x70)
1591
                {
1592
                case DW_EH_PE_textrel:
1593
                  BFD_ASSERT (hdr_info == NULL);
1594
                  break;
1595
                case DW_EH_PE_datarel:
1596
                  {
1597
                    switch (abfd->arch_info->arch)
1598
                      {
1599
                      case bfd_arch_ia64:
1600
                        BFD_ASSERT (elf_gp (abfd) != 0);
1601
                        address += elf_gp (abfd);
1602
                        break;
1603
                      default:
1604
                        (*info->callbacks->einfo)
1605
                          (_("%P: DW_EH_PE_datarel unspecified"
1606
                             " for this architecture.\n"));
1607
                        /* Fall thru */
1608
                      case bfd_arch_frv:
1609
                      case bfd_arch_i386:
1610
                        BFD_ASSERT (htab->hgot != NULL
1611
                                    && ((htab->hgot->root.type
1612
                                         == bfd_link_hash_defined)
1613
                                        || (htab->hgot->root.type
1614
                                            == bfd_link_hash_defweak)));
1615
                        address
1616
                          += (htab->hgot->root.u.def.value
1617
                              + htab->hgot->root.u.def.section->output_offset
1618
                              + (htab->hgot->root.u.def.section->output_section
1619
                                 ->vma));
1620
                        break;
1621
                      }
1622
                  }
1623
                  break;
1624
                case DW_EH_PE_pcrel:
1625
                  value += (bfd_vma) ent->offset - ent->new_offset;
1626
                  address += (sec->output_section->vma
1627
                              + sec->output_offset
1628
                              + ent->offset + 8);
1629
                  break;
1630
                }
1631
              if (ent->make_relative)
1632
                value -= (sec->output_section->vma
1633
                          + sec->output_offset
1634
                          + ent->new_offset + 8);
1635
              write_value (abfd, buf, value, width);
1636
            }
1637
 
1638
          start = buf;
1639
 
1640
          if (hdr_info)
1641
            {
1642
              /* The address calculation may overflow, giving us a
1643
                 value greater than 4G on a 32-bit target when
1644
                 dwarf_vma is 64-bit.  */
1645
              if (sizeof (address) > 4 && ptr_size == 4)
1646
                address &= 0xffffffff;
1647
              hdr_info->array[hdr_info->array_count].initial_loc = address;
1648
              hdr_info->array[hdr_info->array_count++].fde
1649
                = (sec->output_section->vma
1650
                   + sec->output_offset
1651
                   + ent->new_offset);
1652
            }
1653
 
1654
          if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel
1655
              || cie->u.cie.make_lsda_relative)
1656
            {
1657
              buf += ent->lsda_offset;
1658
              width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size);
1659
              value = read_value (abfd, buf, width,
1660
                                  get_DW_EH_PE_signed (ent->lsda_encoding));
1661
              if (value)
1662
                {
1663
                  if ((ent->lsda_encoding & 0x70) == DW_EH_PE_pcrel)
1664
                    value += (bfd_vma) ent->offset - ent->new_offset;
1665
                  else if (cie->u.cie.make_lsda_relative)
1666
                    value -= (sec->output_section->vma
1667
                              + sec->output_offset
1668
                              + ent->new_offset + 8 + ent->lsda_offset);
1669
                  write_value (abfd, buf, value, width);
1670
                }
1671
            }
1672
          else if (ent->add_augmentation_size)
1673
            {
1674
              /* Skip the PC and length and insert a zero byte for the
1675
                 augmentation size.  */
1676
              buf += width * 2;
1677
              memmove (buf + 1, buf, end - buf);
1678
              *buf = 0;
1679
            }
1680
 
1681
          if (ent->set_loc)
1682
            {
1683
              /* Adjust DW_CFA_set_loc.  */
1684
              unsigned int cnt;
1685
              bfd_vma new_offset;
1686
 
1687
              width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
1688
              new_offset = ent->new_offset + 8
1689
                           + extra_augmentation_string_bytes (ent)
1690
                           + extra_augmentation_data_bytes (ent);
1691
 
1692
              for (cnt = 1; cnt <= ent->set_loc[0]; cnt++)
1693
                {
1694
                  buf = start + ent->set_loc[cnt];
1695
 
1696
                  value = read_value (abfd, buf, width,
1697
                                      get_DW_EH_PE_signed (ent->fde_encoding));
1698
                  if (!value)
1699
                    continue;
1700
 
1701
                  if ((ent->fde_encoding & 0x70) == DW_EH_PE_pcrel)
1702
                    value += (bfd_vma) ent->offset + 8 - new_offset;
1703
                  if (ent->make_relative)
1704
                    value -= (sec->output_section->vma
1705
                              + sec->output_offset
1706
                              + new_offset + ent->set_loc[cnt]);
1707
                  write_value (abfd, buf, value, width);
1708
                }
1709
            }
1710
        }
1711
    }
1712
 
1713
  /* We don't align the section to its section alignment since the
1714
     runtime library only expects all CIE/FDE records aligned at
1715
     the pointer size. _bfd_elf_discard_section_eh_frame should
1716
     have padded CIE/FDE records to multiple of pointer size with
1717
     size_of_output_cie_fde.  */
1718
  if ((sec->size % ptr_size) != 0)
1719
    abort ();
1720
 
1721
  /* FIXME: octets_per_byte.  */
1722
  return bfd_set_section_contents (abfd, sec->output_section,
1723
                                   contents, (file_ptr) sec->output_offset,
1724
                                   sec->size);
1725
}
1726
 
1727
/* Helper function used to sort .eh_frame_hdr search table by increasing
1728
   VMA of FDE initial location.  */
1729
 
1730
static int
1731
vma_compare (const void *a, const void *b)
1732
{
1733
  const struct eh_frame_array_ent *p = (const struct eh_frame_array_ent *) a;
1734
  const struct eh_frame_array_ent *q = (const struct eh_frame_array_ent *) b;
1735
  if (p->initial_loc > q->initial_loc)
1736
    return 1;
1737
  if (p->initial_loc < q->initial_loc)
1738
    return -1;
1739
  return 0;
1740
}
1741
 
1742
/* Write out .eh_frame_hdr section.  This must be called after
1743
   _bfd_elf_write_section_eh_frame has been called on all input
1744
   .eh_frame sections.
1745
   .eh_frame_hdr format:
1746
   ubyte version                (currently 1)
1747
   ubyte eh_frame_ptr_enc       (DW_EH_PE_* encoding of pointer to start of
1748
                                 .eh_frame section)
1749
   ubyte fde_count_enc          (DW_EH_PE_* encoding of total FDE count
1750
                                 number (or DW_EH_PE_omit if there is no
1751
                                 binary search table computed))
1752
   ubyte table_enc              (DW_EH_PE_* encoding of binary search table,
1753
                                 or DW_EH_PE_omit if not present.
1754
                                 DW_EH_PE_datarel is using address of
1755
                                 .eh_frame_hdr section start as base)
1756
   [encoded] eh_frame_ptr       (pointer to start of .eh_frame section)
1757
   optionally followed by:
1758
   [encoded] fde_count          (total number of FDEs in .eh_frame section)
1759
   fde_count x [encoded] initial_loc, fde
1760
                                (array of encoded pairs containing
1761
                                 FDE initial_location field and FDE address,
1762
                                 sorted by increasing initial_loc).  */
1763
 
1764
bfd_boolean
1765
_bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
1766
{
1767
  struct elf_link_hash_table *htab;
1768
  struct eh_frame_hdr_info *hdr_info;
1769
  asection *sec;
1770
  bfd_byte *contents;
1771
  asection *eh_frame_sec;
1772
  bfd_size_type size;
1773
  bfd_boolean retval;
1774
  bfd_vma encoded_eh_frame;
1775
 
1776
  htab = elf_hash_table (info);
1777
  hdr_info = &htab->eh_info;
1778
  sec = hdr_info->hdr_sec;
1779
  if (sec == NULL)
1780
    return TRUE;
1781
 
1782
  size = EH_FRAME_HDR_SIZE;
1783
  if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1784
    size += 4 + hdr_info->fde_count * 8;
1785
  contents = (bfd_byte *) bfd_malloc (size);
1786
  if (contents == NULL)
1787
    return FALSE;
1788
 
1789
  eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
1790
  if (eh_frame_sec == NULL)
1791
    {
1792
      free (contents);
1793
      return FALSE;
1794
    }
1795
 
1796
  memset (contents, 0, EH_FRAME_HDR_SIZE);
1797
  contents[0] = 1;                               /* Version.  */
1798
  contents[1] = get_elf_backend_data (abfd)->elf_backend_encode_eh_address
1799
    (abfd, info, eh_frame_sec, 0, sec, 4,
1800
     &encoded_eh_frame);                        /* .eh_frame offset.  */
1801
 
1802
  if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1803
    {
1804
      contents[2] = DW_EH_PE_udata4;            /* FDE count encoding.  */
1805
      contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* Search table enc.  */
1806
    }
1807
  else
1808
    {
1809
      contents[2] = DW_EH_PE_omit;
1810
      contents[3] = DW_EH_PE_omit;
1811
    }
1812
  bfd_put_32 (abfd, encoded_eh_frame, contents + 4);
1813
 
1814
  if (contents[2] != DW_EH_PE_omit)
1815
    {
1816
      unsigned int i;
1817
 
1818
      bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
1819
      qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
1820
             vma_compare);
1821
      for (i = 0; i < hdr_info->fde_count; i++)
1822
        {
1823
          bfd_put_32 (abfd,
1824
                      hdr_info->array[i].initial_loc
1825
                      - sec->output_section->vma,
1826
                      contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
1827
          bfd_put_32 (abfd,
1828
                      hdr_info->array[i].fde - sec->output_section->vma,
1829
                      contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
1830
        }
1831
    }
1832
 
1833
  /* FIXME: octets_per_byte.  */
1834
  retval = bfd_set_section_contents (abfd, sec->output_section,
1835
                                     contents, (file_ptr) sec->output_offset,
1836
                                     sec->size);
1837
  free (contents);
1838
  return retval;
1839
}
1840
 
1841
/* Return the width of FDE addresses.  This is the default implementation.  */
1842
 
1843
unsigned int
1844
_bfd_elf_eh_frame_address_size (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
1845
{
1846
  return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64 ? 8 : 4;
1847
}
1848
 
1849
/* Decide whether we can use a PC-relative encoding within the given
1850
   EH frame section.  This is the default implementation.  */
1851
 
1852
bfd_boolean
1853
_bfd_elf_can_make_relative (bfd *input_bfd ATTRIBUTE_UNUSED,
1854
                            struct bfd_link_info *info ATTRIBUTE_UNUSED,
1855
                            asection *eh_frame_section ATTRIBUTE_UNUSED)
1856
{
1857
  return TRUE;
1858
}
1859
 
1860
/* Select an encoding for the given address.  Preference is given to
1861
   PC-relative addressing modes.  */
1862
 
1863
bfd_byte
1864
_bfd_elf_encode_eh_address (bfd *abfd ATTRIBUTE_UNUSED,
1865
                            struct bfd_link_info *info ATTRIBUTE_UNUSED,
1866
                            asection *osec, bfd_vma offset,
1867
                            asection *loc_sec, bfd_vma loc_offset,
1868
                            bfd_vma *encoded)
1869
{
1870
  *encoded = osec->vma + offset -
1871
    (loc_sec->output_section->vma + loc_sec->output_offset + loc_offset);
1872
  return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
1873
}

powered by: WebSVN 2.1.0

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