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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [bfd/] [elf-eh-frame.c] - Blame information for rev 24

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

Line No. Rev Author Line
1 24 jeremybenn
/* .eh_frame section optimization.
2
   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007
3
   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 "elf/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 = e1;
219
  const struct cie *c2 = 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 = 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
/* Called before calling _bfd_elf_parse_eh_frame on every input bfd's
427
   .eh_frame section.  */
428
 
429
void
430
_bfd_elf_begin_eh_frame_parsing (struct bfd_link_info *info)
431
{
432
  struct eh_frame_hdr_info *hdr_info;
433
 
434
  hdr_info = &elf_hash_table (info)->eh_info;
435
  hdr_info->merge_cies = !info->relocatable;
436
}
437
 
438
/* Try to parse .eh_frame section SEC, which belongs to ABFD.  Store the
439
   information in the section's sec_info field on success.  COOKIE
440
   describes the relocations in SEC.  */
441
 
442
void
443
_bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
444
                         asection *sec, struct elf_reloc_cookie *cookie)
445
{
446
#define REQUIRE(COND)                                   \
447
  do                                                    \
448
    if (!(COND))                                        \
449
      goto free_no_table;                               \
450
  while (0)
451
 
452
  bfd_byte *ehbuf = NULL, *buf, *end;
453
  bfd_byte *last_fde;
454
  struct eh_cie_fde *this_inf;
455
  unsigned int hdr_length, hdr_id;
456
  unsigned int cie_count;
457
  struct cie *cie, *local_cies = NULL;
458
  struct elf_link_hash_table *htab;
459
  struct eh_frame_hdr_info *hdr_info;
460
  struct eh_frame_sec_info *sec_info = NULL;
461
  unsigned int ptr_size;
462
  unsigned int num_cies;
463
  unsigned int num_entries;
464
  elf_gc_mark_hook_fn gc_mark_hook;
465
 
466
  htab = elf_hash_table (info);
467
  hdr_info = &htab->eh_info;
468
  if (hdr_info->parsed_eh_frames)
469
    return;
470
 
471
  if (sec->size == 0)
472
    {
473
      /* This file does not contain .eh_frame information.  */
474
      return;
475
    }
476
 
477
  if (bfd_is_abs_section (sec->output_section))
478
    {
479
      /* At least one of the sections is being discarded from the
480
         link, so we should just ignore them.  */
481
      return;
482
    }
483
 
484
  /* Read the frame unwind information from abfd.  */
485
 
486
  REQUIRE (bfd_malloc_and_get_section (abfd, sec, &ehbuf));
487
 
488
  if (sec->size >= 4
489
      && bfd_get_32 (abfd, ehbuf) == 0
490
      && cookie->rel == cookie->relend)
491
    {
492
      /* Empty .eh_frame section.  */
493
      free (ehbuf);
494
      return;
495
    }
496
 
497
  /* If .eh_frame section size doesn't fit into int, we cannot handle
498
     it (it would need to use 64-bit .eh_frame format anyway).  */
499
  REQUIRE (sec->size == (unsigned int) sec->size);
500
 
501
  ptr_size = (get_elf_backend_data (abfd)
502
              ->elf_backend_eh_frame_address_size (abfd, sec));
503
  REQUIRE (ptr_size != 0);
504
 
505
  /* Go through the section contents and work out how many FDEs and
506
     CIEs there are.  */
507
  buf = ehbuf;
508
  end = ehbuf + sec->size;
509
  num_cies = 0;
510
  num_entries = 0;
511
  while (buf != end)
512
    {
513
      num_entries++;
514
 
515
      /* Read the length of the entry.  */
516
      REQUIRE (skip_bytes (&buf, end, 4));
517
      hdr_length = bfd_get_32 (abfd, buf - 4);
518
 
519
      /* 64-bit .eh_frame is not supported.  */
520
      REQUIRE (hdr_length != 0xffffffff);
521
      if (hdr_length == 0)
522
        break;
523
 
524
      REQUIRE (skip_bytes (&buf, end, 4));
525
      hdr_id = bfd_get_32 (abfd, buf - 4);
526
      if (hdr_id == 0)
527
        num_cies++;
528
 
529
      REQUIRE (skip_bytes (&buf, end, hdr_length - 4));
530
    }
531
 
532
  sec_info = bfd_zmalloc (sizeof (struct eh_frame_sec_info)
533
                          + (num_entries - 1) * sizeof (struct eh_cie_fde));
534
  REQUIRE (sec_info);
535
 
536
  /* We need to have a "struct cie" for each CIE in this section.  */
537
  local_cies = bfd_zmalloc (num_cies * sizeof (*local_cies));
538
  REQUIRE (local_cies);
539
 
540
#define ENSURE_NO_RELOCS(buf)                           \
541
  REQUIRE (!(cookie->rel < cookie->relend               \
542
             && (cookie->rel->r_offset                  \
543
                 < (bfd_size_type) ((buf) - ehbuf))     \
544
             && cookie->rel->r_info != 0))
545
 
546
#define SKIP_RELOCS(buf)                                \
547
  while (cookie->rel < cookie->relend                   \
548
         && (cookie->rel->r_offset                      \
549
             < (bfd_size_type) ((buf) - ehbuf)))        \
550
    cookie->rel++
551
 
552
#define GET_RELOC(buf)                                  \
553
  ((cookie->rel < cookie->relend                        \
554
    && (cookie->rel->r_offset                           \
555
        == (bfd_size_type) ((buf) - ehbuf)))            \
556
   ? cookie->rel : NULL)
557
 
558
  buf = ehbuf;
559
  cie_count = 0;
560
  gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook;
561
  while ((bfd_size_type) (buf - ehbuf) != sec->size)
562
    {
563
      char *aug;
564
      bfd_byte *start, *insns, *insns_end;
565
      bfd_size_type length;
566
      unsigned int set_loc_count;
567
 
568
      this_inf = sec_info->entry + sec_info->count;
569
      last_fde = buf;
570
 
571
      /* Read the length of the entry.  */
572
      REQUIRE (skip_bytes (&buf, ehbuf + sec->size, 4));
573
      hdr_length = bfd_get_32 (abfd, buf - 4);
574
 
575
      /* The CIE/FDE must be fully contained in this input section.  */
576
      REQUIRE ((bfd_size_type) (buf - ehbuf) + hdr_length <= sec->size);
577
      end = buf + hdr_length;
578
 
579
      this_inf->offset = last_fde - ehbuf;
580
      this_inf->size = 4 + hdr_length;
581
      this_inf->reloc_index = cookie->rel - cookie->rels;
582
 
583
      if (hdr_length == 0)
584
        {
585
          /* A zero-length CIE should only be found at the end of
586
             the section.  */
587
          REQUIRE ((bfd_size_type) (buf - ehbuf) == sec->size);
588
          ENSURE_NO_RELOCS (buf);
589
          sec_info->count++;
590
          break;
591
        }
592
 
593
      REQUIRE (skip_bytes (&buf, end, 4));
594
      hdr_id = bfd_get_32 (abfd, buf - 4);
595
 
596
      if (hdr_id == 0)
597
        {
598
          unsigned int initial_insn_length;
599
 
600
          /* CIE  */
601
          this_inf->cie = 1;
602
 
603
          /* Point CIE to one of the section-local cie structures.  */
604
          cie = local_cies + cie_count++;
605
 
606
          cie->cie_inf = this_inf;
607
          cie->length = hdr_length;
608
          cie->output_sec = sec->output_section;
609
          start = buf;
610
          REQUIRE (read_byte (&buf, end, &cie->version));
611
 
612
          /* Cannot handle unknown versions.  */
613
          REQUIRE (cie->version == 1 || cie->version == 3);
614
          REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation));
615
 
616
          strcpy (cie->augmentation, (char *) buf);
617
          buf = (bfd_byte *) strchr ((char *) buf, '\0') + 1;
618
          ENSURE_NO_RELOCS (buf);
619
          if (buf[0] == 'e' && buf[1] == 'h')
620
            {
621
              /* GCC < 3.0 .eh_frame CIE */
622
              /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
623
                 is private to each CIE, so we don't need it for anything.
624
                 Just skip it.  */
625
              REQUIRE (skip_bytes (&buf, end, ptr_size));
626
              SKIP_RELOCS (buf);
627
            }
628
          REQUIRE (read_uleb128 (&buf, end, &cie->code_align));
629
          REQUIRE (read_sleb128 (&buf, end, &cie->data_align));
630
          if (cie->version == 1)
631
            {
632
              REQUIRE (buf < end);
633
              cie->ra_column = *buf++;
634
            }
635
          else
636
            REQUIRE (read_uleb128 (&buf, end, &cie->ra_column));
637
          ENSURE_NO_RELOCS (buf);
638
          cie->lsda_encoding = DW_EH_PE_omit;
639
          cie->fde_encoding = DW_EH_PE_omit;
640
          cie->per_encoding = DW_EH_PE_omit;
641
          aug = cie->augmentation;
642
          if (aug[0] != 'e' || aug[1] != 'h')
643
            {
644
              if (*aug == 'z')
645
                {
646
                  aug++;
647
                  REQUIRE (read_uleb128 (&buf, end, &cie->augmentation_size));
648
                  ENSURE_NO_RELOCS (buf);
649
                }
650
 
651
              while (*aug != '\0')
652
                switch (*aug++)
653
                  {
654
                  case 'L':
655
                    REQUIRE (read_byte (&buf, end, &cie->lsda_encoding));
656
                    ENSURE_NO_RELOCS (buf);
657
                    REQUIRE (get_DW_EH_PE_width (cie->lsda_encoding, ptr_size));
658
                    break;
659
                  case 'R':
660
                    REQUIRE (read_byte (&buf, end, &cie->fde_encoding));
661
                    ENSURE_NO_RELOCS (buf);
662
                    REQUIRE (get_DW_EH_PE_width (cie->fde_encoding, ptr_size));
663
                    break;
664
                  case 'S':
665
                    break;
666
                  case 'P':
667
                    {
668
                      int per_width;
669
 
670
                      REQUIRE (read_byte (&buf, end, &cie->per_encoding));
671
                      per_width = get_DW_EH_PE_width (cie->per_encoding,
672
                                                      ptr_size);
673
                      REQUIRE (per_width);
674
                      if ((cie->per_encoding & 0xf0) == DW_EH_PE_aligned)
675
                        {
676
                          length = -(buf - ehbuf) & (per_width - 1);
677
                          REQUIRE (skip_bytes (&buf, end, length));
678
                        }
679
                      ENSURE_NO_RELOCS (buf);
680
                      /* Ensure we have a reloc here.  */
681
                      REQUIRE (GET_RELOC (buf));
682
                      cie->personality.reloc_index
683
                        = cookie->rel - cookie->rels;
684
                      /* Cope with MIPS-style composite relocations.  */
685
                      do
686
                        cookie->rel++;
687
                      while (GET_RELOC (buf) != NULL);
688
                      REQUIRE (skip_bytes (&buf, end, per_width));
689
                    }
690
                    break;
691
                  default:
692
                    /* Unrecognized augmentation. Better bail out.  */
693
                    goto free_no_table;
694
                  }
695
            }
696
 
697
          /* For shared libraries, try to get rid of as many RELATIVE relocs
698
             as possible.  */
699
          if (info->shared
700
              && (get_elf_backend_data (abfd)
701
                  ->elf_backend_can_make_relative_eh_frame
702
                  (abfd, info, sec)))
703
            {
704
              if ((cie->fde_encoding & 0xf0) == DW_EH_PE_absptr)
705
                this_inf->make_relative = 1;
706
              /* If the CIE doesn't already have an 'R' entry, it's fairly
707
                 easy to add one, provided that there's no aligned data
708
                 after the augmentation string.  */
709
              else if (cie->fde_encoding == DW_EH_PE_omit
710
                       && (cie->per_encoding & 0xf0) != DW_EH_PE_aligned)
711
                {
712
                  if (*cie->augmentation == 0)
713
                    this_inf->add_augmentation_size = 1;
714
                  this_inf->u.cie.add_fde_encoding = 1;
715
                  this_inf->make_relative = 1;
716
                }
717
            }
718
 
719
          if (info->shared
720
              && (get_elf_backend_data (abfd)
721
                  ->elf_backend_can_make_lsda_relative_eh_frame
722
                  (abfd, info, sec))
723
              && (cie->lsda_encoding & 0xf0) == DW_EH_PE_absptr)
724
            cie->can_make_lsda_relative = 1;
725
 
726
          /* If FDE encoding was not specified, it defaults to
727
             DW_EH_absptr.  */
728
          if (cie->fde_encoding == DW_EH_PE_omit)
729
            cie->fde_encoding = DW_EH_PE_absptr;
730
 
731
          initial_insn_length = end - buf;
732
          if (initial_insn_length <= sizeof (cie->initial_instructions))
733
            {
734
              cie->initial_insn_length = initial_insn_length;
735
              memcpy (cie->initial_instructions, buf, initial_insn_length);
736
            }
737
          insns = buf;
738
          buf += initial_insn_length;
739
          ENSURE_NO_RELOCS (buf);
740
 
741
          if (hdr_info->merge_cies)
742
            this_inf->u.cie.u.full_cie = cie;
743
          this_inf->u.cie.per_encoding_relative
744
            = (cie->per_encoding & 0x70) == DW_EH_PE_pcrel;
745
        }
746
      else
747
        {
748
          asection *rsec;
749
 
750
          /* Find the corresponding CIE.  */
751
          unsigned int cie_offset = this_inf->offset + 4 - hdr_id;
752
          for (cie = local_cies; cie < local_cies + cie_count; cie++)
753
            if (cie_offset == cie->cie_inf->offset)
754
              break;
755
 
756
          /* Ensure this FDE references one of the CIEs in this input
757
             section.  */
758
          REQUIRE (cie != local_cies + cie_count);
759
          this_inf->u.fde.cie_inf = cie->cie_inf;
760
          this_inf->make_relative = cie->cie_inf->make_relative;
761
          this_inf->add_augmentation_size
762
            = cie->cie_inf->add_augmentation_size;
763
 
764
          ENSURE_NO_RELOCS (buf);
765
          REQUIRE (GET_RELOC (buf));
766
 
767
          /* Chain together the FDEs for each section.  */
768
          rsec = _bfd_elf_gc_mark_rsec (info, sec, gc_mark_hook, cookie);
769
          REQUIRE (rsec && rsec->owner == abfd);
770
          this_inf->u.fde.next_for_section = elf_fde_list (rsec);
771
          elf_fde_list (rsec) = this_inf;
772
 
773
          /* Skip the initial location and address range.  */
774
          start = buf;
775
          length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
776
          REQUIRE (skip_bytes (&buf, end, 2 * length));
777
 
778
          /* Skip the augmentation size, if present.  */
779
          if (cie->augmentation[0] == 'z')
780
            REQUIRE (read_uleb128 (&buf, end, &length));
781
          else
782
            length = 0;
783
 
784
          /* Of the supported augmentation characters above, only 'L'
785
             adds augmentation data to the FDE.  This code would need to
786
             be adjusted if any future augmentations do the same thing.  */
787
          if (cie->lsda_encoding != DW_EH_PE_omit)
788
            {
789
              SKIP_RELOCS (buf);
790
              if (cie->can_make_lsda_relative && GET_RELOC (buf))
791
                cie->cie_inf->u.cie.make_lsda_relative = 1;
792
              this_inf->lsda_offset = buf - start;
793
              /* If there's no 'z' augmentation, we don't know where the
794
                 CFA insns begin.  Assume no padding.  */
795
              if (cie->augmentation[0] != 'z')
796
                length = end - buf;
797
            }
798
 
799
          /* Skip over the augmentation data.  */
800
          REQUIRE (skip_bytes (&buf, end, length));
801
          insns = buf;
802
 
803
          buf = last_fde + 4 + hdr_length;
804
          SKIP_RELOCS (buf);
805
        }
806
 
807
      /* Try to interpret the CFA instructions and find the first
808
         padding nop.  Shrink this_inf's size so that it doesn't
809
         include the padding.  */
810
      length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
811
      set_loc_count = 0;
812
      insns_end = skip_non_nops (insns, end, length, &set_loc_count);
813
      /* If we don't understand the CFA instructions, we can't know
814
         what needs to be adjusted there.  */
815
      if (insns_end == NULL
816
          /* For the time being we don't support DW_CFA_set_loc in
817
             CIE instructions.  */
818
          || (set_loc_count && this_inf->cie))
819
        goto free_no_table;
820
      this_inf->size -= end - insns_end;
821
      if (insns_end != end && this_inf->cie)
822
        {
823
          cie->initial_insn_length -= end - insns_end;
824
          cie->length -= end - insns_end;
825
        }
826
      if (set_loc_count
827
          && ((cie->fde_encoding & 0xf0) == DW_EH_PE_pcrel
828
              || this_inf->make_relative))
829
        {
830
          unsigned int cnt;
831
          bfd_byte *p;
832
 
833
          this_inf->set_loc = bfd_malloc ((set_loc_count + 1)
834
                                          * sizeof (unsigned int));
835
          REQUIRE (this_inf->set_loc);
836
          this_inf->set_loc[0] = set_loc_count;
837
          p = insns;
838
          cnt = 0;
839
          while (p < end)
840
            {
841
              if (*p == DW_CFA_set_loc)
842
                this_inf->set_loc[++cnt] = p + 1 - start;
843
              REQUIRE (skip_cfa_op (&p, end, length));
844
            }
845
        }
846
 
847
      this_inf->removed = 1;
848
      this_inf->fde_encoding = cie->fde_encoding;
849
      this_inf->lsda_encoding = cie->lsda_encoding;
850
      sec_info->count++;
851
    }
852
  BFD_ASSERT (sec_info->count == num_entries);
853
  BFD_ASSERT (cie_count == num_cies);
854
 
855
  elf_section_data (sec)->sec_info = sec_info;
856
  sec->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
857
  if (hdr_info->merge_cies)
858
    {
859
      sec_info->cies = local_cies;
860
      local_cies = NULL;
861
    }
862
  goto success;
863
 
864
 free_no_table:
865
  (*info->callbacks->einfo)
866
    (_("%P: error in %B(%A); no .eh_frame_hdr table will be created.\n"),
867
     abfd, sec);
868
  hdr_info->table = FALSE;
869
  if (sec_info)
870
    free (sec_info);
871
 success:
872
  if (ehbuf)
873
    free (ehbuf);
874
  if (local_cies)
875
    free (local_cies);
876
#undef REQUIRE
877
}
878
 
879
/* Finish a pass over all .eh_frame sections.  */
880
 
881
void
882
_bfd_elf_end_eh_frame_parsing (struct bfd_link_info *info)
883
{
884
  struct eh_frame_hdr_info *hdr_info;
885
 
886
  hdr_info = &elf_hash_table (info)->eh_info;
887
  hdr_info->parsed_eh_frames = TRUE;
888
}
889
 
890
/* Mark all relocations against CIE or FDE ENT, which occurs in
891
   .eh_frame section SEC.  COOKIE describes the relocations in SEC;
892
   its "rel" field can be changed freely.  */
893
 
894
static bfd_boolean
895
mark_entry (struct bfd_link_info *info, asection *sec,
896
            struct eh_cie_fde *ent, elf_gc_mark_hook_fn gc_mark_hook,
897
            struct elf_reloc_cookie *cookie)
898
{
899
  for (cookie->rel = cookie->rels + ent->reloc_index;
900
       cookie->rel < cookie->relend
901
         && cookie->rel->r_offset < ent->offset + ent->size;
902
       cookie->rel++)
903
    if (!_bfd_elf_gc_mark_reloc (info, sec, gc_mark_hook, cookie))
904
      return FALSE;
905
 
906
  return TRUE;
907
}
908
 
909
/* Mark all the relocations against FDEs that relate to code in input
910
   section SEC.  The FDEs belong to .eh_frame section EH_FRAME, whose
911
   relocations are described by COOKIE.  */
912
 
913
bfd_boolean
914
_bfd_elf_gc_mark_fdes (struct bfd_link_info *info, asection *sec,
915
                       asection *eh_frame, elf_gc_mark_hook_fn gc_mark_hook,
916
                       struct elf_reloc_cookie *cookie)
917
{
918
  struct eh_cie_fde *fde, *cie;
919
 
920
  for (fde = elf_fde_list (sec); fde; fde = fde->u.fde.next_for_section)
921
    {
922
      if (!mark_entry (info, eh_frame, fde, gc_mark_hook, cookie))
923
        return FALSE;
924
 
925
      /* At this stage, all cie_inf fields point to local CIEs, so we
926
         can use the same cookie to refer to them.  */
927
      cie = fde->u.fde.cie_inf;
928
      if (!cie->u.cie.gc_mark)
929
        {
930
          cie->u.cie.gc_mark = 1;
931
          if (!mark_entry (info, eh_frame, cie, gc_mark_hook, cookie))
932
            return FALSE;
933
        }
934
    }
935
  return TRUE;
936
}
937
 
938
/* Input section SEC of ABFD is an .eh_frame section that contains the
939
   CIE described by CIE_INF.  Return a version of CIE_INF that is going
940
   to be kept in the output, adding CIE_INF to the output if necessary.
941
 
942
   HDR_INFO is the .eh_frame_hdr information and COOKIE describes the
943
   relocations in REL.  */
944
 
945
static struct eh_cie_fde *
946
find_merged_cie (bfd *abfd, asection *sec,
947
                 struct eh_frame_hdr_info *hdr_info,
948
                 struct elf_reloc_cookie *cookie,
949
                 struct eh_cie_fde *cie_inf)
950
{
951
  unsigned long r_symndx;
952
  struct cie *cie, *new_cie;
953
  Elf_Internal_Rela *rel;
954
  void **loc;
955
 
956
  /* Use CIE_INF if we have already decided to keep it.  */
957
  if (!cie_inf->removed)
958
    return cie_inf;
959
 
960
  /* If we have merged CIE_INF with another CIE, use that CIE instead.  */
961
  if (cie_inf->u.cie.merged)
962
    return cie_inf->u.cie.u.merged_with;
963
 
964
  cie = cie_inf->u.cie.u.full_cie;
965
 
966
  /* Assume we will need to keep CIE_INF.  */
967
  cie_inf->removed = 0;
968
  cie_inf->u.cie.u.sec = sec;
969
 
970
  /* If we are not merging CIEs, use CIE_INF.  */
971
  if (cie == NULL)
972
    return cie_inf;
973
 
974
  if (cie->per_encoding != DW_EH_PE_omit)
975
    {
976
      /* Work out the address of personality routine, either as an absolute
977
         value or as a symbol.  */
978
      rel = cookie->rels + cie->personality.reloc_index;
979
      memset (&cie->personality, 0, sizeof (cie->personality));
980
#ifdef BFD64
981
      if (elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64)
982
        r_symndx = ELF64_R_SYM (rel->r_info);
983
      else
984
#endif
985
        r_symndx = ELF32_R_SYM (rel->r_info);
986
      if (r_symndx >= cookie->locsymcount
987
          || ELF_ST_BIND (cookie->locsyms[r_symndx].st_info) != STB_LOCAL)
988
        {
989
          struct elf_link_hash_entry *h;
990
 
991
          r_symndx -= cookie->extsymoff;
992
          h = cookie->sym_hashes[r_symndx];
993
 
994
          while (h->root.type == bfd_link_hash_indirect
995
                 || h->root.type == bfd_link_hash_warning)
996
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
997
 
998
          cie->personality.h = h;
999
        }
1000
      else
1001
        {
1002
          Elf_Internal_Sym *sym;
1003
          asection *sym_sec;
1004
 
1005
          sym = &cookie->locsyms[r_symndx];
1006
          sym_sec = bfd_section_from_elf_index (abfd, sym->st_shndx);
1007
          if (sym_sec == NULL)
1008
            return cie_inf;
1009
 
1010
          if (sym_sec->kept_section != NULL)
1011
            sym_sec = sym_sec->kept_section;
1012
          if (sym_sec->output_section == NULL)
1013
            return cie_inf;
1014
 
1015
          cie->local_personality = 1;
1016
          cie->personality.val = (sym->st_value
1017
                                  + sym_sec->output_offset
1018
                                  + sym_sec->output_section->vma);
1019
        }
1020
    }
1021
 
1022
  /* See if we can merge this CIE with an earlier one.  */
1023
  cie->output_sec = sec->output_section;
1024
  cie_compute_hash (cie);
1025
  if (hdr_info->cies == NULL)
1026
    {
1027
      hdr_info->cies = htab_try_create (1, cie_hash, cie_eq, free);
1028
      if (hdr_info->cies == NULL)
1029
        return cie_inf;
1030
    }
1031
  loc = htab_find_slot_with_hash (hdr_info->cies, cie, cie->hash, INSERT);
1032
  if (loc == NULL)
1033
    return cie_inf;
1034
 
1035
  new_cie = (struct cie *) *loc;
1036
  if (new_cie == NULL)
1037
    {
1038
      /* Keep CIE_INF and record it in the hash table.  */
1039
      new_cie = malloc (sizeof (struct cie));
1040
      if (new_cie == NULL)
1041
        return cie_inf;
1042
 
1043
      memcpy (new_cie, cie, sizeof (struct cie));
1044
      *loc = new_cie;
1045
    }
1046
  else
1047
    {
1048
      /* Merge CIE_INF with NEW_CIE->CIE_INF.  */
1049
      cie_inf->removed = 1;
1050
      cie_inf->u.cie.merged = 1;
1051
      cie_inf->u.cie.u.merged_with = new_cie->cie_inf;
1052
      if (cie_inf->u.cie.make_lsda_relative)
1053
        new_cie->cie_inf->u.cie.make_lsda_relative = 1;
1054
    }
1055
  return new_cie->cie_inf;
1056
}
1057
 
1058
/* This function is called for each input file before the .eh_frame
1059
   section is relocated.  It discards duplicate CIEs and FDEs for discarded
1060
   functions.  The function returns TRUE iff any entries have been
1061
   deleted.  */
1062
 
1063
bfd_boolean
1064
_bfd_elf_discard_section_eh_frame
1065
   (bfd *abfd, struct bfd_link_info *info, asection *sec,
1066
    bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *),
1067
    struct elf_reloc_cookie *cookie)
1068
{
1069
  struct eh_cie_fde *ent;
1070
  struct eh_frame_sec_info *sec_info;
1071
  struct eh_frame_hdr_info *hdr_info;
1072
  unsigned int ptr_size, offset;
1073
 
1074
  sec_info = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
1075
  if (sec_info == NULL)
1076
    return FALSE;
1077
 
1078
  hdr_info = &elf_hash_table (info)->eh_info;
1079
  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
1080
    if (!ent->cie)
1081
      {
1082
        cookie->rel = cookie->rels + ent->reloc_index;
1083
        BFD_ASSERT (cookie->rel < cookie->relend
1084
                    && cookie->rel->r_offset == ent->offset + 8);
1085
        if (!(*reloc_symbol_deleted_p) (ent->offset + 8, cookie))
1086
          {
1087
            if (info->shared
1088
                && (((ent->fde_encoding & 0xf0) == DW_EH_PE_absptr
1089
                     && ent->make_relative == 0)
1090
                    || (ent->fde_encoding & 0xf0) == DW_EH_PE_aligned))
1091
              {
1092
                /* If a shared library uses absolute pointers
1093
                   which we cannot turn into PC relative,
1094
                   don't create the binary search table,
1095
                   since it is affected by runtime relocations.  */
1096
                hdr_info->table = FALSE;
1097
                (*info->callbacks->einfo)
1098
                  (_("%P: fde encoding in %B(%A) prevents .eh_frame_hdr"
1099
                     " table being created.\n"), abfd, sec);
1100
              }
1101
            ent->removed = 0;
1102
            hdr_info->fde_count++;
1103
            ent->u.fde.cie_inf = find_merged_cie (abfd, sec, hdr_info, cookie,
1104
                                                  ent->u.fde.cie_inf);
1105
          }
1106
      }
1107
 
1108
  if (sec_info->cies)
1109
    {
1110
      free (sec_info->cies);
1111
      sec_info->cies = NULL;
1112
    }
1113
 
1114
  ptr_size = (get_elf_backend_data (sec->owner)
1115
              ->elf_backend_eh_frame_address_size (sec->owner, sec));
1116
  offset = 0;
1117
  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
1118
    if (!ent->removed)
1119
      {
1120
        ent->new_offset = offset;
1121
        offset += size_of_output_cie_fde (ent, ptr_size);
1122
      }
1123
 
1124
  sec->rawsize = sec->size;
1125
  sec->size = offset;
1126
  return offset != sec->rawsize;
1127
}
1128
 
1129
/* This function is called for .eh_frame_hdr section after
1130
   _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
1131
   input sections.  It finalizes the size of .eh_frame_hdr section.  */
1132
 
1133
bfd_boolean
1134
_bfd_elf_discard_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
1135
{
1136
  struct elf_link_hash_table *htab;
1137
  struct eh_frame_hdr_info *hdr_info;
1138
  asection *sec;
1139
 
1140
  htab = elf_hash_table (info);
1141
  hdr_info = &htab->eh_info;
1142
 
1143
  if (hdr_info->cies != NULL)
1144
    {
1145
      htab_delete (hdr_info->cies);
1146
      hdr_info->cies = NULL;
1147
    }
1148
 
1149
  sec = hdr_info->hdr_sec;
1150
  if (sec == NULL)
1151
    return FALSE;
1152
 
1153
  sec->size = EH_FRAME_HDR_SIZE;
1154
  if (hdr_info->table)
1155
    sec->size += 4 + hdr_info->fde_count * 8;
1156
 
1157
  elf_tdata (abfd)->eh_frame_hdr = sec;
1158
  return TRUE;
1159
}
1160
 
1161
/* This function is called from size_dynamic_sections.
1162
   It needs to decide whether .eh_frame_hdr should be output or not,
1163
   because when the dynamic symbol table has been sized it is too late
1164
   to strip sections.  */
1165
 
1166
bfd_boolean
1167
_bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info)
1168
{
1169
  asection *o;
1170
  bfd *abfd;
1171
  struct elf_link_hash_table *htab;
1172
  struct eh_frame_hdr_info *hdr_info;
1173
 
1174
  htab = elf_hash_table (info);
1175
  hdr_info = &htab->eh_info;
1176
  if (hdr_info->hdr_sec == NULL)
1177
    return TRUE;
1178
 
1179
  if (bfd_is_abs_section (hdr_info->hdr_sec->output_section))
1180
    {
1181
      hdr_info->hdr_sec = NULL;
1182
      return TRUE;
1183
    }
1184
 
1185
  abfd = NULL;
1186
  if (info->eh_frame_hdr)
1187
    for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
1188
      {
1189
        /* Count only sections which have at least a single CIE or FDE.
1190
           There cannot be any CIE or FDE <= 8 bytes.  */
1191
        o = bfd_get_section_by_name (abfd, ".eh_frame");
1192
        if (o && o->size > 8 && !bfd_is_abs_section (o->output_section))
1193
          break;
1194
      }
1195
 
1196
  if (abfd == NULL)
1197
    {
1198
      hdr_info->hdr_sec->flags |= SEC_EXCLUDE;
1199
      hdr_info->hdr_sec = NULL;
1200
      return TRUE;
1201
    }
1202
 
1203
  hdr_info->table = TRUE;
1204
  return TRUE;
1205
}
1206
 
1207
/* Adjust an address in the .eh_frame section.  Given OFFSET within
1208
   SEC, this returns the new offset in the adjusted .eh_frame section,
1209
   or -1 if the address refers to a CIE/FDE which has been removed
1210
   or to offset with dynamic relocation which is no longer needed.  */
1211
 
1212
bfd_vma
1213
_bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
1214
                                  struct bfd_link_info *info,
1215
                                  asection *sec,
1216
                                  bfd_vma offset)
1217
{
1218
  struct eh_frame_sec_info *sec_info;
1219
  struct elf_link_hash_table *htab;
1220
  struct eh_frame_hdr_info *hdr_info;
1221
  unsigned int lo, hi, mid;
1222
 
1223
  if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
1224
    return offset;
1225
  sec_info = elf_section_data (sec)->sec_info;
1226
 
1227
  if (offset >= sec->rawsize)
1228
    return offset - sec->rawsize + sec->size;
1229
 
1230
  htab = elf_hash_table (info);
1231
  hdr_info = &htab->eh_info;
1232
 
1233
  lo = 0;
1234
  hi = sec_info->count;
1235
  mid = 0;
1236
  while (lo < hi)
1237
    {
1238
      mid = (lo + hi) / 2;
1239
      if (offset < sec_info->entry[mid].offset)
1240
        hi = mid;
1241
      else if (offset
1242
               >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
1243
        lo = mid + 1;
1244
      else
1245
        break;
1246
    }
1247
 
1248
  BFD_ASSERT (lo < hi);
1249
 
1250
  /* FDE or CIE was removed.  */
1251
  if (sec_info->entry[mid].removed)
1252
    return (bfd_vma) -1;
1253
 
1254
  /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
1255
     relocation against FDE's initial_location field.  */
1256
  if (!sec_info->entry[mid].cie
1257
      && sec_info->entry[mid].make_relative
1258
      && offset == sec_info->entry[mid].offset + 8)
1259
    return (bfd_vma) -2;
1260
 
1261
  /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
1262
     for run-time relocation against LSDA field.  */
1263
  if (!sec_info->entry[mid].cie
1264
      && sec_info->entry[mid].u.fde.cie_inf->u.cie.make_lsda_relative
1265
      && offset == (sec_info->entry[mid].offset + 8
1266
                    + sec_info->entry[mid].lsda_offset))
1267
    return (bfd_vma) -2;
1268
 
1269
  /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
1270
     relocation against DW_CFA_set_loc's arguments.  */
1271
  if (sec_info->entry[mid].set_loc
1272
      && sec_info->entry[mid].make_relative
1273
      && (offset >= sec_info->entry[mid].offset + 8
1274
                    + sec_info->entry[mid].set_loc[1]))
1275
    {
1276
      unsigned int cnt;
1277
 
1278
      for (cnt = 1; cnt <= sec_info->entry[mid].set_loc[0]; cnt++)
1279
        if (offset == sec_info->entry[mid].offset + 8
1280
                      + sec_info->entry[mid].set_loc[cnt])
1281
          return (bfd_vma) -2;
1282
    }
1283
 
1284
  /* Any new augmentation bytes go before the first relocation.  */
1285
  return (offset + sec_info->entry[mid].new_offset
1286
          - sec_info->entry[mid].offset
1287
          + extra_augmentation_string_bytes (sec_info->entry + mid)
1288
          + extra_augmentation_data_bytes (sec_info->entry + mid));
1289
}
1290
 
1291
/* Write out .eh_frame section.  This is called with the relocated
1292
   contents.  */
1293
 
1294
bfd_boolean
1295
_bfd_elf_write_section_eh_frame (bfd *abfd,
1296
                                 struct bfd_link_info *info,
1297
                                 asection *sec,
1298
                                 bfd_byte *contents)
1299
{
1300
  struct eh_frame_sec_info *sec_info;
1301
  struct elf_link_hash_table *htab;
1302
  struct eh_frame_hdr_info *hdr_info;
1303
  unsigned int ptr_size;
1304
  struct eh_cie_fde *ent;
1305
 
1306
  if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
1307
    return bfd_set_section_contents (abfd, sec->output_section, contents,
1308
                                     sec->output_offset, sec->size);
1309
 
1310
  ptr_size = (get_elf_backend_data (abfd)
1311
              ->elf_backend_eh_frame_address_size (abfd, sec));
1312
  BFD_ASSERT (ptr_size != 0);
1313
 
1314
  sec_info = elf_section_data (sec)->sec_info;
1315
  htab = elf_hash_table (info);
1316
  hdr_info = &htab->eh_info;
1317
 
1318
  if (hdr_info->table && hdr_info->array == NULL)
1319
    hdr_info->array
1320
      = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
1321
  if (hdr_info->array == NULL)
1322
    hdr_info = NULL;
1323
 
1324
  /* The new offsets can be bigger or smaller than the original offsets.
1325
     We therefore need to make two passes over the section: one backward
1326
     pass to move entries up and one forward pass to move entries down.
1327
     The two passes won't interfere with each other because entries are
1328
     not reordered  */
1329
  for (ent = sec_info->entry + sec_info->count; ent-- != sec_info->entry;)
1330
    if (!ent->removed && ent->new_offset > ent->offset)
1331
      memmove (contents + ent->new_offset, contents + ent->offset, ent->size);
1332
 
1333
  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
1334
    if (!ent->removed && ent->new_offset < ent->offset)
1335
      memmove (contents + ent->new_offset, contents + ent->offset, ent->size);
1336
 
1337
  for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
1338
    {
1339
      unsigned char *buf, *end;
1340
      unsigned int new_size;
1341
 
1342
      if (ent->removed)
1343
        continue;
1344
 
1345
      if (ent->size == 4)
1346
        {
1347
          /* Any terminating FDE must be at the end of the section.  */
1348
          BFD_ASSERT (ent == sec_info->entry + sec_info->count - 1);
1349
          continue;
1350
        }
1351
 
1352
      buf = contents + ent->new_offset;
1353
      end = buf + ent->size;
1354
      new_size = size_of_output_cie_fde (ent, ptr_size);
1355
 
1356
      /* Update the size.  It may be shrinked.  */
1357
      bfd_put_32 (abfd, new_size - 4, buf);
1358
 
1359
      /* Filling the extra bytes with DW_CFA_nops.  */
1360
      if (new_size != ent->size)
1361
        memset (end, 0, new_size - ent->size);
1362
 
1363
      if (ent->cie)
1364
        {
1365
          /* CIE */
1366
          if (ent->make_relative
1367
              || ent->u.cie.make_lsda_relative
1368
              || ent->u.cie.per_encoding_relative)
1369
            {
1370
              char *aug;
1371
              unsigned int action, extra_string, extra_data;
1372
              unsigned int per_width, per_encoding;
1373
 
1374
              /* Need to find 'R' or 'L' augmentation's argument and modify
1375
                 DW_EH_PE_* value.  */
1376
              action = ((ent->make_relative ? 1 : 0)
1377
                        | (ent->u.cie.make_lsda_relative ? 2 : 0)
1378
                        | (ent->u.cie.per_encoding_relative ? 4 : 0));
1379
              extra_string = extra_augmentation_string_bytes (ent);
1380
              extra_data = extra_augmentation_data_bytes (ent);
1381
 
1382
              /* Skip length, id and version.  */
1383
              buf += 9;
1384
              aug = (char *) buf;
1385
              buf += strlen (aug) + 1;
1386
              skip_leb128 (&buf, end);
1387
              skip_leb128 (&buf, end);
1388
              skip_leb128 (&buf, end);
1389
              if (*aug == 'z')
1390
                {
1391
                  /* The uleb128 will always be a single byte for the kind
1392
                     of augmentation strings that we're prepared to handle.  */
1393
                  *buf++ += extra_data;
1394
                  aug++;
1395
                }
1396
 
1397
              /* Make room for the new augmentation string and data bytes.  */
1398
              memmove (buf + extra_string + extra_data, buf, end - buf);
1399
              memmove (aug + extra_string, aug, buf - (bfd_byte *) aug);
1400
              buf += extra_string;
1401
              end += extra_string + extra_data;
1402
 
1403
              if (ent->add_augmentation_size)
1404
                {
1405
                  *aug++ = 'z';
1406
                  *buf++ = extra_data - 1;
1407
                }
1408
              if (ent->u.cie.add_fde_encoding)
1409
                {
1410
                  BFD_ASSERT (action & 1);
1411
                  *aug++ = 'R';
1412
                  *buf++ = DW_EH_PE_pcrel;
1413
                  action &= ~1;
1414
                }
1415
 
1416
              while (action)
1417
                switch (*aug++)
1418
                  {
1419
                  case 'L':
1420
                    if (action & 2)
1421
                      {
1422
                        BFD_ASSERT (*buf == ent->lsda_encoding);
1423
                        *buf |= DW_EH_PE_pcrel;
1424
                        action &= ~2;
1425
                      }
1426
                    buf++;
1427
                    break;
1428
                  case 'P':
1429
                    per_encoding = *buf++;
1430
                    per_width = get_DW_EH_PE_width (per_encoding, ptr_size);
1431
                    BFD_ASSERT (per_width != 0);
1432
                    BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
1433
                                == ent->u.cie.per_encoding_relative);
1434
                    if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
1435
                      buf = (contents
1436
                             + ((buf - contents + per_width - 1)
1437
                                & ~((bfd_size_type) per_width - 1)));
1438
                    if (action & 4)
1439
                      {
1440
                        bfd_vma val;
1441
 
1442
                        val = read_value (abfd, buf, per_width,
1443
                                          get_DW_EH_PE_signed (per_encoding));
1444
                        val += ent->offset - ent->new_offset;
1445
                        val -= extra_string + extra_data;
1446
                        write_value (abfd, buf, val, per_width);
1447
                        action &= ~4;
1448
                      }
1449
                    buf += per_width;
1450
                    break;
1451
                  case 'R':
1452
                    if (action & 1)
1453
                      {
1454
                        BFD_ASSERT (*buf == ent->fde_encoding);
1455
                        *buf |= DW_EH_PE_pcrel;
1456
                        action &= ~1;
1457
                      }
1458
                    buf++;
1459
                    break;
1460
                  case 'S':
1461
                    break;
1462
                  default:
1463
                    BFD_FAIL ();
1464
                  }
1465
            }
1466
        }
1467
      else
1468
        {
1469
          /* FDE */
1470
          bfd_vma value, address;
1471
          unsigned int width;
1472
          bfd_byte *start;
1473
          struct eh_cie_fde *cie;
1474
 
1475
          /* Skip length.  */
1476
          cie = ent->u.fde.cie_inf;
1477
          buf += 4;
1478
          value = ((ent->new_offset + sec->output_offset + 4)
1479
                   - (cie->new_offset + cie->u.cie.u.sec->output_offset));
1480
          bfd_put_32 (abfd, value, buf);
1481
          buf += 4;
1482
          width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
1483
          value = read_value (abfd, buf, width,
1484
                              get_DW_EH_PE_signed (ent->fde_encoding));
1485
          address = value;
1486
          if (value)
1487
            {
1488
              switch (ent->fde_encoding & 0xf0)
1489
                {
1490
                case DW_EH_PE_indirect:
1491
                case DW_EH_PE_textrel:
1492
                  BFD_ASSERT (hdr_info == NULL);
1493
                  break;
1494
                case DW_EH_PE_datarel:
1495
                  {
1496
                    asection *got = bfd_get_section_by_name (abfd, ".got");
1497
 
1498
                    BFD_ASSERT (got != NULL);
1499
                    address += got->vma;
1500
                  }
1501
                  break;
1502
                case DW_EH_PE_pcrel:
1503
                  value += ent->offset - ent->new_offset;
1504
                  address += (sec->output_section->vma
1505
                              + sec->output_offset
1506
                              + ent->offset + 8);
1507
                  break;
1508
                }
1509
              if (ent->make_relative)
1510
                value -= (sec->output_section->vma
1511
                          + sec->output_offset
1512
                          + ent->new_offset + 8);
1513
              write_value (abfd, buf, value, width);
1514
            }
1515
 
1516
          start = buf;
1517
 
1518
          if (hdr_info)
1519
            {
1520
              hdr_info->array[hdr_info->array_count].initial_loc = address;
1521
              hdr_info->array[hdr_info->array_count++].fde
1522
                = (sec->output_section->vma
1523
                   + sec->output_offset
1524
                   + ent->new_offset);
1525
            }
1526
 
1527
          if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel
1528
              || cie->u.cie.make_lsda_relative)
1529
            {
1530
              buf += ent->lsda_offset;
1531
              width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size);
1532
              value = read_value (abfd, buf, width,
1533
                                  get_DW_EH_PE_signed (ent->lsda_encoding));
1534
              if (value)
1535
                {
1536
                  if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel)
1537
                    value += ent->offset - ent->new_offset;
1538
                  else if (cie->u.cie.make_lsda_relative)
1539
                    value -= (sec->output_section->vma
1540
                              + sec->output_offset
1541
                              + ent->new_offset + 8 + ent->lsda_offset);
1542
                  write_value (abfd, buf, value, width);
1543
                }
1544
            }
1545
          else if (ent->add_augmentation_size)
1546
            {
1547
              /* Skip the PC and length and insert a zero byte for the
1548
                 augmentation size.  */
1549
              buf += width * 2;
1550
              memmove (buf + 1, buf, end - buf);
1551
              *buf = 0;
1552
            }
1553
 
1554
          if (ent->set_loc)
1555
            {
1556
              /* Adjust DW_CFA_set_loc.  */
1557
              unsigned int cnt, width;
1558
              bfd_vma new_offset;
1559
 
1560
              width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
1561
              new_offset = ent->new_offset + 8
1562
                           + extra_augmentation_string_bytes (ent)
1563
                           + extra_augmentation_data_bytes (ent);
1564
 
1565
              for (cnt = 1; cnt <= ent->set_loc[0]; cnt++)
1566
                {
1567
                  bfd_vma value;
1568
                  buf = start + ent->set_loc[cnt];
1569
 
1570
                  value = read_value (abfd, buf, width,
1571
                                      get_DW_EH_PE_signed (ent->fde_encoding));
1572
                  if (!value)
1573
                    continue;
1574
 
1575
                  if ((ent->fde_encoding & 0xf0) == DW_EH_PE_pcrel)
1576
                    value += ent->offset + 8 - new_offset;
1577
                  if (ent->make_relative)
1578
                    value -= (sec->output_section->vma
1579
                              + sec->output_offset
1580
                              + new_offset + ent->set_loc[cnt]);
1581
                  write_value (abfd, buf, value, width);
1582
                }
1583
            }
1584
        }
1585
    }
1586
 
1587
  /* We don't align the section to its section alignment since the
1588
     runtime library only expects all CIE/FDE records aligned at
1589
     the pointer size. _bfd_elf_discard_section_eh_frame should
1590
     have padded CIE/FDE records to multiple of pointer size with
1591
     size_of_output_cie_fde.  */
1592
  if ((sec->size % ptr_size) != 0)
1593
    abort ();
1594
 
1595
  return bfd_set_section_contents (abfd, sec->output_section,
1596
                                   contents, (file_ptr) sec->output_offset,
1597
                                   sec->size);
1598
}
1599
 
1600
/* Helper function used to sort .eh_frame_hdr search table by increasing
1601
   VMA of FDE initial location.  */
1602
 
1603
static int
1604
vma_compare (const void *a, const void *b)
1605
{
1606
  const struct eh_frame_array_ent *p = a;
1607
  const struct eh_frame_array_ent *q = b;
1608
  if (p->initial_loc > q->initial_loc)
1609
    return 1;
1610
  if (p->initial_loc < q->initial_loc)
1611
    return -1;
1612
  return 0;
1613
}
1614
 
1615
/* Write out .eh_frame_hdr section.  This must be called after
1616
   _bfd_elf_write_section_eh_frame has been called on all input
1617
   .eh_frame sections.
1618
   .eh_frame_hdr format:
1619
   ubyte version                (currently 1)
1620
   ubyte eh_frame_ptr_enc       (DW_EH_PE_* encoding of pointer to start of
1621
                                 .eh_frame section)
1622
   ubyte fde_count_enc          (DW_EH_PE_* encoding of total FDE count
1623
                                 number (or DW_EH_PE_omit if there is no
1624
                                 binary search table computed))
1625
   ubyte table_enc              (DW_EH_PE_* encoding of binary search table,
1626
                                 or DW_EH_PE_omit if not present.
1627
                                 DW_EH_PE_datarel is using address of
1628
                                 .eh_frame_hdr section start as base)
1629
   [encoded] eh_frame_ptr       (pointer to start of .eh_frame section)
1630
   optionally followed by:
1631
   [encoded] fde_count          (total number of FDEs in .eh_frame section)
1632
   fde_count x [encoded] initial_loc, fde
1633
                                (array of encoded pairs containing
1634
                                 FDE initial_location field and FDE address,
1635
                                 sorted by increasing initial_loc).  */
1636
 
1637
bfd_boolean
1638
_bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
1639
{
1640
  struct elf_link_hash_table *htab;
1641
  struct eh_frame_hdr_info *hdr_info;
1642
  asection *sec;
1643
  bfd_byte *contents;
1644
  asection *eh_frame_sec;
1645
  bfd_size_type size;
1646
  bfd_boolean retval;
1647
  bfd_vma encoded_eh_frame;
1648
 
1649
  htab = elf_hash_table (info);
1650
  hdr_info = &htab->eh_info;
1651
  sec = hdr_info->hdr_sec;
1652
  if (sec == NULL)
1653
    return TRUE;
1654
 
1655
  size = EH_FRAME_HDR_SIZE;
1656
  if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1657
    size += 4 + hdr_info->fde_count * 8;
1658
  contents = bfd_malloc (size);
1659
  if (contents == NULL)
1660
    return FALSE;
1661
 
1662
  eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
1663
  if (eh_frame_sec == NULL)
1664
    {
1665
      free (contents);
1666
      return FALSE;
1667
    }
1668
 
1669
  memset (contents, 0, EH_FRAME_HDR_SIZE);
1670
  contents[0] = 1;                               /* Version.  */
1671
  contents[1] = get_elf_backend_data (abfd)->elf_backend_encode_eh_address
1672
    (abfd, info, eh_frame_sec, 0, sec, 4,
1673
     &encoded_eh_frame);                        /* .eh_frame offset.  */
1674
 
1675
  if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1676
    {
1677
      contents[2] = DW_EH_PE_udata4;            /* FDE count encoding.  */
1678
      contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* Search table enc.  */
1679
    }
1680
  else
1681
    {
1682
      contents[2] = DW_EH_PE_omit;
1683
      contents[3] = DW_EH_PE_omit;
1684
    }
1685
  bfd_put_32 (abfd, encoded_eh_frame, contents + 4);
1686
 
1687
  if (contents[2] != DW_EH_PE_omit)
1688
    {
1689
      unsigned int i;
1690
 
1691
      bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
1692
      qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
1693
             vma_compare);
1694
      for (i = 0; i < hdr_info->fde_count; i++)
1695
        {
1696
          bfd_put_32 (abfd,
1697
                      hdr_info->array[i].initial_loc
1698
                      - sec->output_section->vma,
1699
                      contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
1700
          bfd_put_32 (abfd,
1701
                      hdr_info->array[i].fde - sec->output_section->vma,
1702
                      contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
1703
        }
1704
    }
1705
 
1706
  retval = bfd_set_section_contents (abfd, sec->output_section,
1707
                                     contents, (file_ptr) sec->output_offset,
1708
                                     sec->size);
1709
  free (contents);
1710
  return retval;
1711
}
1712
 
1713
/* Return the width of FDE addresses.  This is the default implementation.  */
1714
 
1715
unsigned int
1716
_bfd_elf_eh_frame_address_size (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
1717
{
1718
  return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64 ? 8 : 4;
1719
}
1720
 
1721
/* Decide whether we can use a PC-relative encoding within the given
1722
   EH frame section.  This is the default implementation.  */
1723
 
1724
bfd_boolean
1725
_bfd_elf_can_make_relative (bfd *input_bfd ATTRIBUTE_UNUSED,
1726
                            struct bfd_link_info *info ATTRIBUTE_UNUSED,
1727
                            asection *eh_frame_section ATTRIBUTE_UNUSED)
1728
{
1729
  return TRUE;
1730
}
1731
 
1732
/* Select an encoding for the given address.  Preference is given to
1733
   PC-relative addressing modes.  */
1734
 
1735
bfd_byte
1736
_bfd_elf_encode_eh_address (bfd *abfd ATTRIBUTE_UNUSED,
1737
                            struct bfd_link_info *info ATTRIBUTE_UNUSED,
1738
                            asection *osec, bfd_vma offset,
1739
                            asection *loc_sec, bfd_vma loc_offset,
1740
                            bfd_vma *encoded)
1741
{
1742
  *encoded = osec->vma + offset -
1743
    (loc_sec->output_section->vma + loc_sec->output_offset + loc_offset);
1744
  return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
1745
}

powered by: WebSVN 2.1.0

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