Merge from vendor branch OPENSSH:
[dragonfly.git] / contrib / binutils-2.14 / bfd / elf-eh-frame.c
1 /* .eh_frame section optimization.
2    Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
3    Written by Jakub Jelinek <jakub@redhat.com>.
4
5    This file is part of BFD, the Binary File Descriptor library.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "elf/dwarf2.h"
26
27 #define EH_FRAME_HDR_SIZE 8
28
29 static bfd_vma read_unsigned_leb128
30   PARAMS ((bfd *, char *, unsigned int *));
31 static bfd_signed_vma read_signed_leb128
32   PARAMS ((bfd *, char *, unsigned int *));
33 static int get_DW_EH_PE_width
34   PARAMS ((int, int));
35 static bfd_vma read_value
36   PARAMS ((bfd *, bfd_byte *, int, int));
37 static void write_value
38   PARAMS ((bfd *, bfd_byte *, bfd_vma, int));
39 static int cie_compare
40   PARAMS ((struct cie *, struct cie *));
41 static int vma_compare
42   PARAMS ((const PTR, const PTR));
43
44 /* Helper function for reading uleb128 encoded data.  */
45
46 static bfd_vma
47 read_unsigned_leb128 (abfd, buf, bytes_read_ptr)
48      bfd *abfd ATTRIBUTE_UNUSED;
49      char *buf;
50      unsigned int *bytes_read_ptr;
51 {
52   bfd_vma  result;
53   unsigned int  num_read;
54   int           shift;
55   unsigned char byte;
56
57   result   = 0;
58   shift    = 0;
59   num_read = 0;
60   do
61     {
62       byte = bfd_get_8 (abfd, (bfd_byte *) buf);
63       buf ++;
64       num_read ++;
65       result |= (((bfd_vma) byte & 0x7f) << shift);
66       shift += 7;
67     }
68   while (byte & 0x80);
69   * bytes_read_ptr = num_read;
70   return result;
71 }
72
73 /* Helper function for reading sleb128 encoded data.  */
74
75 static bfd_signed_vma
76 read_signed_leb128 (abfd, buf, bytes_read_ptr)
77      bfd *abfd ATTRIBUTE_UNUSED;
78      char *buf;
79      unsigned int * bytes_read_ptr;
80 {
81   bfd_vma       result;
82   int           shift;
83   int           num_read;
84   unsigned char byte;
85
86   result = 0;
87   shift = 0;
88   num_read = 0;
89   do
90     {
91       byte = bfd_get_8 (abfd, (bfd_byte *) buf);
92       buf ++;
93       num_read ++;
94       result |= (((bfd_vma) byte & 0x7f) << shift);
95       shift += 7;
96     }
97   while (byte & 0x80);
98   if (byte & 0x40)
99     result |= (((bfd_vma) -1) << (shift - 7)) << 7;
100   * bytes_read_ptr = num_read;
101   return result;
102 }
103
104 #define read_uleb128(VAR, BUF)                                  \
105 do                                                              \
106   {                                                             \
107     (VAR) = read_unsigned_leb128 (abfd, buf, &leb128_tmp);      \
108     (BUF) += leb128_tmp;                                        \
109   }                                                             \
110 while (0)
111
112 #define read_sleb128(VAR, BUF)                                  \
113 do                                                              \
114   {                                                             \
115     (VAR) = read_signed_leb128 (abfd, buf, &leb128_tmp);        \
116     (BUF) += leb128_tmp;                                        \
117   }                                                             \
118 while (0)
119
120 /* Return 0 if either encoding is variable width, or not yet known to bfd.  */
121
122 static
123 int get_DW_EH_PE_width (encoding, ptr_size)
124      int encoding, ptr_size;
125 {
126   /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame
127      was added to bfd.  */
128   if ((encoding & 0x60) == 0x60)
129     return 0;
130
131   switch (encoding & 7)
132     {
133     case DW_EH_PE_udata2: return 2;
134     case DW_EH_PE_udata4: return 4;
135     case DW_EH_PE_udata8: return 8;
136     case DW_EH_PE_absptr: return ptr_size;
137     default:
138       break;
139     }
140
141   return 0;
142 }
143
144 #define get_DW_EH_PE_signed(encoding) (((encoding) & DW_EH_PE_signed) != 0)
145
146 /* Read a width sized value from memory.  */
147
148 static bfd_vma
149 read_value (abfd, buf, width, is_signed)
150      bfd *abfd;
151      bfd_byte *buf;
152      int width;
153      int is_signed;
154 {
155   bfd_vma value;
156
157   switch (width)
158     {
159     case 2:
160       if (is_signed)
161         value = bfd_get_signed_16 (abfd, buf);
162       else
163         value = bfd_get_16 (abfd, buf);
164       break;
165     case 4:
166       if (is_signed)
167         value = bfd_get_signed_32 (abfd, buf);
168       else
169         value = bfd_get_32 (abfd, buf);
170       break;
171     case 8:
172       if (is_signed)
173         value = bfd_get_signed_64 (abfd, buf);
174       else
175         value = bfd_get_64 (abfd, buf);
176       break;
177     default:
178       BFD_FAIL ();
179       return 0;
180     }
181
182   return value;
183 }
184
185 /* Store a width sized value to memory.  */
186
187 static void
188 write_value (abfd, buf, value, width)
189      bfd *abfd;
190      bfd_byte *buf;
191      bfd_vma value;
192      int width;
193 {
194   switch (width)
195     {
196     case 2: bfd_put_16 (abfd, value, buf); break;
197     case 4: bfd_put_32 (abfd, value, buf); break;
198     case 8: bfd_put_64 (abfd, value, buf); break;
199     default: BFD_FAIL ();
200     }
201 }
202
203 /* Return zero if C1 and C2 CIEs can be merged.  */
204
205 static
206 int cie_compare (c1, c2)
207      struct cie *c1, *c2;
208 {
209   if (c1->hdr.length == c2->hdr.length
210       && c1->version == c2->version
211       && strcmp (c1->augmentation, c2->augmentation) == 0
212       && strcmp (c1->augmentation, "eh") != 0
213       && c1->code_align == c2->code_align
214       && c1->data_align == c2->data_align
215       && c1->ra_column == c2->ra_column
216       && c1->augmentation_size == c2->augmentation_size
217       && c1->personality == c2->personality
218       && c1->per_encoding == c2->per_encoding
219       && c1->lsda_encoding == c2->lsda_encoding
220       && c1->fde_encoding == c2->fde_encoding
221       && (c1->initial_insn_length
222           == c2->initial_insn_length)
223       && memcmp (c1->initial_instructions,
224                  c2->initial_instructions,
225                  c1->initial_insn_length) == 0)
226     return 0;
227
228   return 1;
229 }
230
231 /* This function is called for each input file before the .eh_frame
232    section is relocated.  It discards duplicate CIEs and FDEs for discarded
233    functions.  The function returns TRUE iff any entries have been
234    deleted.  */
235
236 bfd_boolean
237 _bfd_elf_discard_section_eh_frame (abfd, info, sec,
238                                    reloc_symbol_deleted_p, cookie)
239      bfd *abfd;
240      struct bfd_link_info *info;
241      asection *sec;
242      bfd_boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));
243      struct elf_reloc_cookie *cookie;
244 {
245   bfd_byte *ehbuf = NULL, *buf;
246   bfd_byte *last_cie, *last_fde;
247   struct cie_header hdr;
248   struct cie cie;
249   struct elf_link_hash_table *htab;
250   struct eh_frame_hdr_info *hdr_info;
251   struct eh_frame_sec_info *sec_info = NULL;
252   unsigned int leb128_tmp;
253   unsigned int cie_usage_count, last_cie_ndx, i, offset;
254   unsigned int make_relative, make_lsda_relative;
255   bfd_size_type new_size;
256   unsigned int ptr_size;
257
258   if (sec->_raw_size == 0)
259     {
260       /* This file does not contain .eh_frame information.  */
261       return FALSE;
262     }
263
264   if ((sec->output_section != NULL
265        && bfd_is_abs_section (sec->output_section)))
266     {
267       /* At least one of the sections is being discarded from the
268          link, so we should just ignore them.  */
269       return FALSE;
270     }
271
272   htab = elf_hash_table (info);
273   hdr_info = &htab->eh_info;
274
275   /* Read the frame unwind information from abfd.  */
276
277   ehbuf = (bfd_byte *) bfd_malloc (sec->_raw_size);
278   if (ehbuf == NULL)
279     goto free_no_table;
280
281   if (! bfd_get_section_contents (abfd, sec, ehbuf, (bfd_vma) 0,
282                                   sec->_raw_size))
283     goto free_no_table;
284
285   if (sec->_raw_size >= 4
286       && bfd_get_32 (abfd, ehbuf) == 0
287       && cookie->rel == cookie->relend)
288     {
289       /* Empty .eh_frame section.  */
290       free (ehbuf);
291       return FALSE;
292     }
293
294   /* If .eh_frame section size doesn't fit into int, we cannot handle
295      it (it would need to use 64-bit .eh_frame format anyway).  */
296   if (sec->_raw_size != (unsigned int) sec->_raw_size)
297     goto free_no_table;
298
299   ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
300               == ELFCLASS64) ? 8 : 4;
301   buf = ehbuf;
302   last_cie = NULL;
303   last_cie_ndx = 0;
304   memset (&cie, 0, sizeof (cie));
305   cie_usage_count = 0;
306   new_size = sec->_raw_size;
307   make_relative = hdr_info->last_cie.make_relative;
308   make_lsda_relative = hdr_info->last_cie.make_lsda_relative;
309   sec_info = bfd_zmalloc (sizeof (struct eh_frame_sec_info)
310                           + 99 * sizeof (struct eh_cie_fde));
311   if (sec_info == NULL)
312     goto free_no_table;
313   sec_info->alloced = 100;
314
315 #define ENSURE_NO_RELOCS(buf)                           \
316   if (cookie->rel < cookie->relend                      \
317       && (cookie->rel->r_offset                         \
318           < (bfd_size_type) ((buf) - ehbuf))            \
319       && cookie->rel->r_info != 0)                      \
320     goto free_no_table
321
322 #define SKIP_RELOCS(buf)                                \
323   while (cookie->rel < cookie->relend                   \
324          && (cookie->rel->r_offset                      \
325              < (bfd_size_type) ((buf) - ehbuf)))        \
326     cookie->rel++
327
328 #define GET_RELOC(buf)                                  \
329   ((cookie->rel < cookie->relend                        \
330     && (cookie->rel->r_offset                           \
331         == (bfd_size_type) ((buf) - ehbuf)))            \
332    ? cookie->rel : NULL)
333
334   for (;;)
335     {
336       unsigned char *aug;
337
338       if (sec_info->count == sec_info->alloced)
339         {
340           sec_info = bfd_realloc (sec_info,
341                                   sizeof (struct eh_frame_sec_info)
342                                   + (sec_info->alloced + 99)
343                                      * sizeof (struct eh_cie_fde));
344           if (sec_info == NULL)
345             goto free_no_table;
346
347           memset (&sec_info->entry[sec_info->alloced], 0,
348                   100 * sizeof (struct eh_cie_fde));
349           sec_info->alloced += 100;
350         }
351
352       last_fde = buf;
353       /* If we are at the end of the section, we still need to decide
354          on whether to output or discard last encountered CIE (if any).  */
355       if ((bfd_size_type) (buf - ehbuf) == sec->_raw_size)
356         hdr.id = (unsigned int) -1;
357       else
358         {
359           if ((bfd_size_type) (buf + 4 - ehbuf) > sec->_raw_size)
360             /* No space for CIE/FDE header length.  */
361             goto free_no_table;
362
363           hdr.length = bfd_get_32 (abfd, buf);
364           if (hdr.length == 0xffffffff)
365             /* 64-bit .eh_frame is not supported.  */
366             goto free_no_table;
367           buf += 4;
368           if ((bfd_size_type) (buf - ehbuf) + hdr.length > sec->_raw_size)
369             /* CIE/FDE not contained fully in this .eh_frame input section.  */
370             goto free_no_table;
371
372           sec_info->entry[sec_info->count].offset = last_fde - ehbuf;
373           sec_info->entry[sec_info->count].size = 4 + hdr.length;
374
375           if (hdr.length == 0)
376             {
377               /* CIE with length 0 must be only the last in the section.  */
378               if ((bfd_size_type) (buf - ehbuf) < sec->_raw_size)
379                 goto free_no_table;
380               ENSURE_NO_RELOCS (buf);
381               sec_info->count++;
382               /* Now just finish last encountered CIE processing and break
383                  the loop.  */
384               hdr.id = (unsigned int) -1;
385             }
386           else
387             {
388               hdr.id = bfd_get_32 (abfd, buf);
389               buf += 4;
390               if (hdr.id == (unsigned int) -1)
391                 goto free_no_table;
392             }
393         }
394
395       if (hdr.id == 0 || hdr.id == (unsigned int) -1)
396         {
397           unsigned int initial_insn_length;
398
399           /* CIE  */
400           if (last_cie != NULL)
401             {
402               /* Now check if this CIE is identical to the last CIE,
403                  in which case we can remove it provided we adjust
404                  all FDEs.  Also, it can be removed if we have removed
405                  all FDEs using it.  */
406               if ((!info->relocateable
407                    && cie_compare (&cie, &hdr_info->last_cie) == 0)
408                   || cie_usage_count == 0)
409                 {
410                   new_size -= cie.hdr.length + 4;
411                   sec_info->entry[last_cie_ndx].removed = 1;
412                   sec_info->entry[last_cie_ndx].sec = hdr_info->last_cie_sec;
413                   sec_info->entry[last_cie_ndx].new_offset
414                     = hdr_info->last_cie_offset;
415                 }
416               else
417                 {
418                   hdr_info->last_cie = cie;
419                   hdr_info->last_cie_sec = sec;
420                   hdr_info->last_cie_offset = last_cie - ehbuf;
421                   sec_info->entry[last_cie_ndx].make_relative
422                     = cie.make_relative;
423                   sec_info->entry[last_cie_ndx].make_lsda_relative
424                     = cie.make_lsda_relative;
425                   sec_info->entry[last_cie_ndx].per_encoding_relative
426                     = (cie.per_encoding & 0x70) == DW_EH_PE_pcrel;
427                 }
428             }
429
430           if (hdr.id == (unsigned int) -1)
431             break;
432
433           last_cie_ndx = sec_info->count;
434           sec_info->entry[sec_info->count].cie = 1;
435
436           cie_usage_count = 0;
437           memset (&cie, 0, sizeof (cie));
438           cie.hdr = hdr;
439           cie.version = *buf++;
440
441           /* Cannot handle unknown versions.  */
442           if (cie.version != 1)
443             goto free_no_table;
444           if (strlen (buf) > sizeof (cie.augmentation) - 1)
445             goto free_no_table;
446
447           strcpy (cie.augmentation, buf);
448           buf = strchr (buf, '\0') + 1;
449           ENSURE_NO_RELOCS (buf);
450           if (buf[0] == 'e' && buf[1] == 'h')
451             {
452               /* GCC < 3.0 .eh_frame CIE */
453               /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
454                  is private to each CIE, so we don't need it for anything.
455                  Just skip it.  */
456               buf += ptr_size;
457               SKIP_RELOCS (buf);
458             }
459           read_uleb128 (cie.code_align, buf);
460           read_sleb128 (cie.data_align, buf);
461           /* Note - in DWARF2 the return address column is an unsigned byte.
462              In DWARF3 it is a ULEB128.  We are following DWARF3.  For most
463              ports this will not matter as the value will be less than 128.
464              For the others (eg FRV, SH, MMIX, IA64) they need a fixed GCC
465              which conforms to the DWARF3 standard.  */
466           read_uleb128 (cie.ra_column, buf);
467           ENSURE_NO_RELOCS (buf);
468           cie.lsda_encoding = DW_EH_PE_omit;
469           cie.fde_encoding = DW_EH_PE_omit;
470           cie.per_encoding = DW_EH_PE_omit;
471           aug = cie.augmentation;
472           if (aug[0] != 'e' || aug[1] != 'h')
473             {
474               if (*aug == 'z')
475                 {
476                   aug++;
477                   read_uleb128 (cie.augmentation_size, buf);
478                   ENSURE_NO_RELOCS (buf);
479                 }
480
481               while (*aug != '\0')
482                 switch (*aug++)
483                   {
484                   case 'L':
485                     cie.lsda_encoding = *buf++;
486                     ENSURE_NO_RELOCS (buf);
487                     if (get_DW_EH_PE_width (cie.lsda_encoding, ptr_size) == 0)
488                       goto free_no_table;
489                     break;
490                   case 'R':
491                     cie.fde_encoding = *buf++;
492                     ENSURE_NO_RELOCS (buf);
493                     if (get_DW_EH_PE_width (cie.fde_encoding, ptr_size) == 0)
494                       goto free_no_table;
495                     break;
496                   case 'P':
497                     {
498                       int per_width;
499
500                       cie.per_encoding = *buf++;
501                       per_width = get_DW_EH_PE_width (cie.per_encoding,
502                                                       ptr_size);
503                       if (per_width == 0)
504                         goto free_no_table;
505                       if ((cie.per_encoding & 0xf0) == DW_EH_PE_aligned)
506                         buf = (ehbuf
507                                + ((buf - ehbuf + per_width - 1)
508                                   & ~((bfd_size_type) per_width - 1)));
509                       ENSURE_NO_RELOCS (buf);
510                       /* Ensure we have a reloc here, against
511                          a global symbol.  */
512                       if (GET_RELOC (buf) != NULL)
513                         {
514                           unsigned long r_symndx;
515
516 #ifdef BFD64
517                           if (ptr_size == 8)
518                             r_symndx = ELF64_R_SYM (cookie->rel->r_info);
519                           else
520 #endif
521                             r_symndx = ELF32_R_SYM (cookie->rel->r_info);
522                           if (r_symndx >= cookie->locsymcount)
523                             {
524                               struct elf_link_hash_entry *h;
525
526                               r_symndx -= cookie->extsymoff;
527                               h = cookie->sym_hashes[r_symndx];
528
529                               while (h->root.type == bfd_link_hash_indirect
530                                      || h->root.type == bfd_link_hash_warning)
531                                 h = (struct elf_link_hash_entry *)
532                                     h->root.u.i.link;
533
534                               cie.personality = h;
535                             }
536                           cookie->rel++;
537                         }
538                       buf += per_width;
539                     }
540                     break;
541                   default:
542                     /* Unrecognized augmentation. Better bail out.  */
543                     goto free_no_table;
544                   }
545             }
546
547           /* For shared libraries, try to get rid of as many RELATIVE relocs
548              as possible.  */
549           if (info->shared
550               && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
551             cie.make_relative = 1;
552
553           if (info->shared
554               && (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
555             cie.make_lsda_relative = 1;
556
557           /* If FDE encoding was not specified, it defaults to
558              DW_EH_absptr.  */
559           if (cie.fde_encoding == DW_EH_PE_omit)
560             cie.fde_encoding = DW_EH_PE_absptr;
561
562           initial_insn_length = cie.hdr.length - (buf - last_fde - 4);
563           if (initial_insn_length <= 50)
564             {
565               cie.initial_insn_length = initial_insn_length;
566               memcpy (cie.initial_instructions, buf, initial_insn_length);
567             }
568           buf += initial_insn_length;
569           ENSURE_NO_RELOCS (buf);
570           last_cie = last_fde;
571         }
572       else
573         {
574           /* Ensure this FDE uses the last CIE encountered.  */
575           if (last_cie == NULL
576               || hdr.id != (unsigned int) (buf - 4 - last_cie))
577             goto free_no_table;
578
579           ENSURE_NO_RELOCS (buf);
580           if (GET_RELOC (buf) == NULL)
581             /* This should not happen.  */
582             goto free_no_table;
583           if ((*reloc_symbol_deleted_p) (buf - ehbuf, cookie))
584             {
585               /* This is a FDE against a discarded section.  It should
586                  be deleted.  */
587               new_size -= hdr.length + 4;
588               sec_info->entry[sec_info->count].removed = 1;
589             }
590           else
591             {
592               if (info->shared
593                   && (((cie.fde_encoding & 0xf0) == DW_EH_PE_absptr
594                        && cie.make_relative == 0)
595                       || (cie.fde_encoding & 0xf0) == DW_EH_PE_aligned))
596                 {
597                   /* If a shared library uses absolute pointers
598                      which we cannot turn into PC relative,
599                      don't create the binary search table,
600                      since it is affected by runtime relocations.  */
601                   hdr_info->table = FALSE;
602                 }
603               cie_usage_count++;
604               hdr_info->fde_count++;
605             }
606           if (cie.lsda_encoding != DW_EH_PE_omit)
607             {
608               unsigned int dummy;
609
610               aug = buf;
611               buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size);
612               if (cie.augmentation[0] == 'z')
613                 read_uleb128 (dummy, buf);
614               /* If some new augmentation data is added before LSDA
615                  in FDE augmentation area, this need to be adjusted.  */
616               sec_info->entry[sec_info->count].lsda_offset = (buf - aug);
617             }
618           buf = last_fde + 4 + hdr.length;
619           SKIP_RELOCS (buf);
620         }
621
622       sec_info->entry[sec_info->count].fde_encoding = cie.fde_encoding;
623       sec_info->entry[sec_info->count].lsda_encoding = cie.lsda_encoding;
624       sec_info->count++;
625     }
626
627   elf_section_data (sec)->sec_info = sec_info;
628   sec->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
629
630   /* Ok, now we can assign new offsets.  */
631   offset = 0;
632   last_cie_ndx = 0;
633   for (i = 0; i < sec_info->count; i++)
634     {
635       if (! sec_info->entry[i].removed)
636         {
637           sec_info->entry[i].new_offset = offset;
638           offset += sec_info->entry[i].size;
639           if (sec_info->entry[i].cie)
640             {
641               last_cie_ndx = i;
642               make_relative = sec_info->entry[i].make_relative;
643               make_lsda_relative = sec_info->entry[i].make_lsda_relative;
644             }
645           else
646             {
647               sec_info->entry[i].make_relative = make_relative;
648               sec_info->entry[i].make_lsda_relative = make_lsda_relative;
649               sec_info->entry[i].per_encoding_relative = 0;
650             }
651         }
652       else if (sec_info->entry[i].cie && sec_info->entry[i].sec == sec)
653         {
654           /* Need to adjust new_offset too.  */
655           BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
656                       == sec_info->entry[i].new_offset);
657           sec_info->entry[i].new_offset
658             = sec_info->entry[last_cie_ndx].new_offset;
659         }
660     }
661   if (hdr_info->last_cie_sec == sec)
662     {
663       BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
664                   == hdr_info->last_cie_offset);
665       hdr_info->last_cie_offset = sec_info->entry[last_cie_ndx].new_offset;
666     }
667
668   /* FIXME: Currently it is not possible to shrink sections to zero size at
669      this point, so build a fake minimal CIE.  */
670   if (new_size == 0)
671     new_size = 16;
672
673   /* Shrink the sec as needed.  */
674   sec->_cooked_size = new_size;
675   if (sec->_cooked_size == 0)
676     sec->flags |= SEC_EXCLUDE;
677
678   free (ehbuf);
679   return new_size != sec->_raw_size;
680
681 free_no_table:
682   if (ehbuf)
683     free (ehbuf);
684   if (sec_info)
685     free (sec_info);
686   hdr_info->table = FALSE;
687   hdr_info->last_cie.hdr.length = 0;
688   return FALSE;
689 }
690
691 /* This function is called for .eh_frame_hdr section after
692    _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
693    input sections.  It finalizes the size of .eh_frame_hdr section.  */
694
695 bfd_boolean
696 _bfd_elf_discard_section_eh_frame_hdr (abfd, info)
697      bfd *abfd;
698      struct bfd_link_info *info;
699 {
700   struct elf_link_hash_table *htab;
701   struct eh_frame_hdr_info *hdr_info;
702   asection *sec;
703
704   htab = elf_hash_table (info);
705   hdr_info = &htab->eh_info;
706   sec = hdr_info->hdr_sec;
707   if (sec == NULL)
708     return FALSE;
709
710   sec->_cooked_size = EH_FRAME_HDR_SIZE;
711   if (hdr_info->table)
712     sec->_cooked_size += 4 + hdr_info->fde_count * 8;
713
714   /* Request program headers to be recalculated.  */
715   elf_tdata (abfd)->program_header_size = 0;
716   elf_tdata (abfd)->eh_frame_hdr = sec;
717   return TRUE;
718 }
719
720 /* This function is called from size_dynamic_sections.
721    It needs to decide whether .eh_frame_hdr should be output or not,
722    because later on it is too late for calling _bfd_strip_section_from_output,
723    since dynamic symbol table has been sized.  */
724
725 bfd_boolean
726 _bfd_elf_maybe_strip_eh_frame_hdr (info)
727      struct bfd_link_info *info;
728 {
729   asection *o;
730   bfd *abfd;
731   struct elf_link_hash_table *htab;
732   struct eh_frame_hdr_info *hdr_info;
733
734   htab = elf_hash_table (info);
735   hdr_info = &htab->eh_info;
736   if (hdr_info->hdr_sec == NULL)
737     return TRUE;
738
739   if (bfd_is_abs_section (hdr_info->hdr_sec->output_section))
740     {
741       hdr_info->hdr_sec = NULL;
742       return TRUE;
743     }
744
745   abfd = NULL;
746   if (info->eh_frame_hdr)
747     for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
748       {
749         /* Count only sections which have at least a single CIE or FDE.
750            There cannot be any CIE or FDE <= 8 bytes.  */
751         o = bfd_get_section_by_name (abfd, ".eh_frame");
752         if (o && o->_raw_size > 8 && !bfd_is_abs_section (o->output_section))
753           break;
754       }
755
756   if (abfd == NULL)
757     {
758       _bfd_strip_section_from_output (info, hdr_info->hdr_sec);
759       hdr_info->hdr_sec = NULL;
760       return TRUE;
761     }
762
763   hdr_info->table = TRUE;
764   return TRUE;
765 }
766
767 /* Adjust an address in the .eh_frame section.  Given OFFSET within
768    SEC, this returns the new offset in the adjusted .eh_frame section,
769    or -1 if the address refers to a CIE/FDE which has been removed
770    or to offset with dynamic relocation which is no longer needed.  */
771
772 bfd_vma
773 _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
774      bfd *output_bfd ATTRIBUTE_UNUSED;
775      asection *sec;
776      bfd_vma offset;
777 {
778   struct eh_frame_sec_info *sec_info;
779   unsigned int lo, hi, mid;
780
781   if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
782     return offset;
783   sec_info = (struct eh_frame_sec_info *)
784              elf_section_data (sec)->sec_info;
785
786   if (offset >= sec->_raw_size)
787     return offset - (sec->_cooked_size - sec->_raw_size);
788
789   lo = 0;
790   hi = sec_info->count;
791   mid = 0;
792   while (lo < hi)
793     {
794       mid = (lo + hi) / 2;
795       if (offset < sec_info->entry[mid].offset)
796         hi = mid;
797       else if (offset
798                >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
799         lo = mid + 1;
800       else
801         break;
802     }
803
804   BFD_ASSERT (lo < hi);
805
806   /* FDE or CIE was removed.  */
807   if (sec_info->entry[mid].removed)
808     return (bfd_vma) -1;
809
810   /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
811      relocation against FDE's initial_location field.  */
812   if (sec_info->entry[mid].make_relative
813       && ! sec_info->entry[mid].cie
814       && offset == sec_info->entry[mid].offset + 8)
815     return (bfd_vma) -2;
816
817   /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
818      for run-time relocation against LSDA field.  */
819   if (sec_info->entry[mid].make_lsda_relative
820       && ! sec_info->entry[mid].cie
821       && (offset == (sec_info->entry[mid].offset + 8
822                      + sec_info->entry[mid].lsda_offset)))
823     return (bfd_vma) -2;
824
825   return (offset + sec_info->entry[mid].new_offset
826           - sec_info->entry[mid].offset);
827 }
828
829 /* Write out .eh_frame section.  This is called with the relocated
830    contents.  */
831
832 bfd_boolean
833 _bfd_elf_write_section_eh_frame (abfd, info, sec, contents)
834      bfd *abfd;
835      struct bfd_link_info *info;
836      asection *sec;
837      bfd_byte *contents;
838 {
839   struct eh_frame_sec_info *sec_info;
840   struct elf_link_hash_table *htab;
841   struct eh_frame_hdr_info *hdr_info;
842   unsigned int i;
843   bfd_byte *p, *buf;
844   unsigned int leb128_tmp;
845   unsigned int cie_offset = 0;
846   unsigned int ptr_size;
847
848   ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
849               == ELFCLASS64) ? 8 : 4;
850
851   if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
852     return bfd_set_section_contents (abfd, sec->output_section,
853                                      contents,
854                                      (file_ptr) sec->output_offset,
855                                      sec->_raw_size);
856   sec_info = (struct eh_frame_sec_info *)
857              elf_section_data (sec)->sec_info;
858   htab = elf_hash_table (info);
859   hdr_info = &htab->eh_info;
860   if (hdr_info->table && hdr_info->array == NULL)
861     hdr_info->array
862       = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
863   if (hdr_info->array == NULL)
864     hdr_info = NULL;
865
866   p = contents;
867   for (i = 0; i < sec_info->count; ++i)
868     {
869       if (sec_info->entry[i].removed)
870         {
871           if (sec_info->entry[i].cie)
872             {
873               /* If CIE is removed due to no remaining FDEs referencing it
874                  and there were no CIEs kept before it, sec_info->entry[i].sec
875                  will be zero.  */
876               if (sec_info->entry[i].sec == NULL)
877                 cie_offset = 0;
878               else
879                 {
880                   cie_offset = sec_info->entry[i].new_offset;
881                   cie_offset += (sec_info->entry[i].sec->output_section->vma
882                                  + sec_info->entry[i].sec->output_offset
883                                  - sec->output_section->vma
884                                  - sec->output_offset);
885                 }
886             }
887           continue;
888         }
889
890       if (sec_info->entry[i].cie)
891         {
892           /* CIE */
893           cie_offset = sec_info->entry[i].new_offset;
894           if (sec_info->entry[i].make_relative
895               || sec_info->entry[i].make_lsda_relative
896               || sec_info->entry[i].per_encoding_relative)
897             {
898               unsigned char *aug;
899               unsigned int action;
900               unsigned int dummy, per_width, per_encoding;
901
902               /* Need to find 'R' or 'L' augmentation's argument and modify
903                  DW_EH_PE_* value.  */
904               action = (sec_info->entry[i].make_relative ? 1 : 0)
905                        | (sec_info->entry[i].make_lsda_relative ? 2 : 0)
906                        | (sec_info->entry[i].per_encoding_relative ? 4 : 0);
907               buf = contents + sec_info->entry[i].offset;
908               /* Skip length, id and version.  */
909               buf += 9;
910               aug = buf;
911               buf = strchr (buf, '\0') + 1;
912               read_uleb128 (dummy, buf);
913               read_sleb128 (dummy, buf);
914               read_uleb128 (dummy, buf);
915               if (*aug == 'z')
916                 {
917                   read_uleb128 (dummy, buf);
918                   aug++;
919                 }
920
921               while (action)
922                 switch (*aug++)
923                   {
924                   case 'L':
925                     if (action & 2)
926                       {
927                         BFD_ASSERT (*buf == sec_info->entry[i].lsda_encoding);
928                         *buf |= DW_EH_PE_pcrel;
929                         action &= ~2;
930                       }
931                     buf++;
932                     break;
933                   case 'P':
934                     per_encoding = *buf++;
935                     per_width = get_DW_EH_PE_width (per_encoding,
936                                                     ptr_size);
937                     BFD_ASSERT (per_width != 0);
938                     BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
939                                 == sec_info->entry[i].per_encoding_relative);
940                     if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
941                       buf = (contents
942                              + ((buf - contents + per_width - 1)
943                                 & ~((bfd_size_type) per_width - 1)));
944                     if (action & 4)
945                       {
946                         bfd_vma value;
947
948                         value = read_value (abfd, buf, per_width,
949                                             get_DW_EH_PE_signed
950                                             (per_encoding));
951                         value += (sec_info->entry[i].offset
952                                   - sec_info->entry[i].new_offset);
953                         write_value (abfd, buf, value, per_width);
954                         action &= ~4;
955                       }
956                     buf += per_width;
957                     break;
958                   case 'R':
959                     if (action & 1)
960                       {
961                         BFD_ASSERT (*buf == sec_info->entry[i].fde_encoding);
962                         *buf |= DW_EH_PE_pcrel;
963                         action &= ~1;
964                       }
965                     buf++;
966                     break;
967                   default:
968                     BFD_FAIL ();
969                   }
970             }
971         }
972       else if (sec_info->entry[i].size > 4)
973         {
974           /* FDE */
975           bfd_vma value = 0, address;
976           unsigned int width;
977
978           buf = contents + sec_info->entry[i].offset;
979           /* Skip length.  */
980           buf += 4;
981           bfd_put_32 (abfd,
982                       sec_info->entry[i].new_offset + 4 - cie_offset, buf);
983           buf += 4;
984           width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding,
985                                       ptr_size);
986           address = value = read_value (abfd, buf, width,
987                                         get_DW_EH_PE_signed
988                                         (sec_info->entry[i].fde_encoding));
989           if (value)
990             {
991               switch (sec_info->entry[i].fde_encoding & 0xf0)
992                 {
993                 case DW_EH_PE_indirect:
994                 case DW_EH_PE_textrel:
995                   BFD_ASSERT (hdr_info == NULL);
996                   break;
997                 case DW_EH_PE_datarel:
998                   {
999                     asection *got = bfd_get_section_by_name (abfd, ".got");
1000
1001                     BFD_ASSERT (got != NULL);
1002                     address += got->vma;
1003                   }
1004                   break;
1005                 case DW_EH_PE_pcrel:
1006                   value += (sec_info->entry[i].offset
1007                             - sec_info->entry[i].new_offset);
1008                   address += (sec->output_section->vma + sec->output_offset
1009                               + sec_info->entry[i].offset + 8);
1010                   break;
1011                 }
1012               if (sec_info->entry[i].make_relative)
1013                 value -= (sec->output_section->vma + sec->output_offset
1014                           + sec_info->entry[i].new_offset + 8);
1015               write_value (abfd, buf, value, width);
1016             }
1017
1018           if (hdr_info)
1019             {
1020               hdr_info->array[hdr_info->array_count].initial_loc = address;
1021               hdr_info->array[hdr_info->array_count++].fde
1022                 = (sec->output_section->vma + sec->output_offset
1023                    + sec_info->entry[i].new_offset);
1024             }
1025
1026           if ((sec_info->entry[i].lsda_encoding & 0xf0) == DW_EH_PE_pcrel
1027               || sec_info->entry[i].make_lsda_relative)
1028             {
1029               buf += sec_info->entry[i].lsda_offset;
1030               width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding,
1031                                           ptr_size);
1032               value = read_value (abfd, buf, width,
1033                                   get_DW_EH_PE_signed
1034                                   (sec_info->entry[i].lsda_encoding));
1035               if (value)
1036                 {
1037                   if ((sec_info->entry[i].lsda_encoding & 0xf0)
1038                       == DW_EH_PE_pcrel)
1039                     value += (sec_info->entry[i].offset
1040                               - sec_info->entry[i].new_offset);
1041                   else if (sec_info->entry[i].make_lsda_relative)
1042                     value -= (sec->output_section->vma + sec->output_offset
1043                               + sec_info->entry[i].new_offset + 8
1044                               + sec_info->entry[i].lsda_offset);
1045                   write_value (abfd, buf, value, width);
1046                 }
1047             }
1048         }
1049       else
1050         /* Terminating FDE must be at the end of .eh_frame section only.  */
1051         BFD_ASSERT (i == sec_info->count - 1);
1052
1053       BFD_ASSERT (p == contents + sec_info->entry[i].new_offset);
1054       memmove (p, contents + sec_info->entry[i].offset,
1055                sec_info->entry[i].size);
1056       p += sec_info->entry[i].size;
1057     }
1058
1059   /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
1060      shrink sections to zero size, this won't be needed any more.  */
1061   if (p == contents && sec->_cooked_size == 16)
1062     {
1063       bfd_put_32 (abfd, 12, p);         /* Fake CIE length */
1064       bfd_put_32 (abfd, 0, p + 4);      /* Fake CIE id */
1065       p[8] = 1;                         /* Fake CIE version */
1066       memset (p + 9, 0, 7);             /* Fake CIE augmentation, 3xleb128
1067                                            and 3xDW_CFA_nop as pad  */
1068       p += 16;
1069     }
1070
1071   BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);
1072
1073   return bfd_set_section_contents (abfd, sec->output_section,
1074                                    contents, (file_ptr) sec->output_offset,
1075                                    sec->_cooked_size);
1076 }
1077
1078 /* Helper function used to sort .eh_frame_hdr search table by increasing
1079    VMA of FDE initial location.  */
1080
1081 static int
1082 vma_compare (a, b)
1083      const PTR a;
1084      const PTR b;
1085 {
1086   struct eh_frame_array_ent *p = (struct eh_frame_array_ent *) a;
1087   struct eh_frame_array_ent *q = (struct eh_frame_array_ent *) b;
1088   if (p->initial_loc > q->initial_loc)
1089     return 1;
1090   if (p->initial_loc < q->initial_loc)
1091     return -1;
1092   return 0;
1093 }
1094
1095 /* Write out .eh_frame_hdr section.  This must be called after
1096    _bfd_elf_write_section_eh_frame has been called on all input
1097    .eh_frame sections.
1098    .eh_frame_hdr format:
1099    ubyte version                (currently 1)
1100    ubyte eh_frame_ptr_enc       (DW_EH_PE_* encoding of pointer to start of
1101                                  .eh_frame section)
1102    ubyte fde_count_enc          (DW_EH_PE_* encoding of total FDE count
1103                                  number (or DW_EH_PE_omit if there is no
1104                                  binary search table computed))
1105    ubyte table_enc              (DW_EH_PE_* encoding of binary search table,
1106                                  or DW_EH_PE_omit if not present.
1107                                  DW_EH_PE_datarel is using address of
1108                                  .eh_frame_hdr section start as base)
1109    [encoded] eh_frame_ptr       (pointer to start of .eh_frame section)
1110    optionally followed by:
1111    [encoded] fde_count          (total number of FDEs in .eh_frame section)
1112    fde_count x [encoded] initial_loc, fde
1113                                 (array of encoded pairs containing
1114                                  FDE initial_location field and FDE address,
1115                                  sorted by increasing initial_loc).  */
1116
1117 bfd_boolean
1118 _bfd_elf_write_section_eh_frame_hdr (abfd, info)
1119      bfd *abfd;
1120      struct bfd_link_info *info;
1121 {
1122   struct elf_link_hash_table *htab;
1123   struct eh_frame_hdr_info *hdr_info;
1124   asection *sec;
1125   bfd_byte *contents;
1126   asection *eh_frame_sec;
1127   bfd_size_type size;
1128   bfd_boolean retval;
1129
1130   htab = elf_hash_table (info);
1131   hdr_info = &htab->eh_info;
1132   sec = hdr_info->hdr_sec;
1133   if (sec == NULL)
1134     return TRUE;
1135
1136   size = EH_FRAME_HDR_SIZE;
1137   if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1138     size += 4 + hdr_info->fde_count * 8;
1139   contents = bfd_malloc (size);
1140   if (contents == NULL)
1141     return FALSE;
1142
1143   eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
1144   if (eh_frame_sec == NULL)
1145     {
1146       free (contents);
1147       return FALSE;
1148     }
1149
1150   memset (contents, 0, EH_FRAME_HDR_SIZE);
1151   contents[0] = 1;                              /* Version.  */
1152   contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset.  */
1153   if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1154     {
1155       contents[2] = DW_EH_PE_udata4;            /* FDE count encoding.  */
1156       contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* Search table enc.  */
1157     }
1158   else
1159     {
1160       contents[2] = DW_EH_PE_omit;
1161       contents[3] = DW_EH_PE_omit;
1162     }
1163   bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
1164               contents + 4);
1165   if (contents[2] != DW_EH_PE_omit)
1166     {
1167       unsigned int i;
1168
1169       bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
1170       qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
1171              vma_compare);
1172       for (i = 0; i < hdr_info->fde_count; i++)
1173         {
1174           bfd_put_32 (abfd,
1175                       hdr_info->array[i].initial_loc
1176                       - sec->output_section->vma,
1177                       contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
1178           bfd_put_32 (abfd,
1179                       hdr_info->array[i].fde - sec->output_section->vma,
1180                       contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
1181         }
1182     }
1183
1184   retval = bfd_set_section_contents (abfd, sec->output_section,
1185                                      contents, (file_ptr) sec->output_offset,
1186                                      sec->_cooked_size);
1187   free (contents);
1188   return retval;
1189 }