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