* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): If new_size
[external/binutils.git] / bfd / elf-eh-frame.c
1 /* .eh_frame section optimization.
2    Copyright 2001 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
871           + (sec_info->entry[mid].new_offset - 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               cie_offset = sec_info->entry[i].new_offset;
923               cie_offset += (sec_info->entry[i].sec->output_section->vma
924                              + sec_info->entry[i].sec->output_offset
925                              - sec->output_section->vma
926                              - sec->output_offset);
927             }
928           continue;
929         }
930       if (sec_info->entry[i].cie)
931         {
932           /* CIE */
933           cie_offset = sec_info->entry[i].new_offset;
934           if (sec_info->entry[i].make_relative
935               || sec_info->entry[i].make_lsda_relative)
936             {
937               unsigned char *aug;
938               unsigned int action;
939               unsigned int dummy, per_width, per_encoding;
940
941               /* Need to find 'R' or 'L' augmentation's argument and modify
942                  DW_EH_PE_* value.  */
943               action = (sec_info->entry[i].make_relative ? 1 : 0)
944                        | (sec_info->entry[i].make_lsda_relative ? 2 : 0);
945               buf = contents + sec_info->entry[i].offset;
946               /* Skip length, id and version.  */
947               buf += 9;
948               aug = buf;
949               buf = strchr (buf, '\0') + 1;
950               read_uleb128 (dummy, buf);
951               read_sleb128 (dummy, buf);
952               read_uleb128 (dummy, buf);
953               if (*aug == 'z')
954                 {
955                   read_uleb128 (dummy, buf);
956                   aug++;
957                 }
958
959               while (action)
960                 switch (*aug++)
961                   {
962                   case 'L':
963                     if (action & 2)
964                       {
965                         BFD_ASSERT (*buf == sec_info->entry[i].lsda_encoding);
966                         *buf |= DW_EH_PE_pcrel;
967                         action &= ~2;
968                       }
969                     buf++;
970                     break;
971                   case 'P':
972                     per_encoding = *buf++;
973                     per_width = get_DW_EH_PE_width (per_encoding,
974                                                     ptr_size);
975                     BFD_ASSERT (per_width != 0);
976                     if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
977                       buf = (contents
978                              + ((buf - contents + per_width - 1)
979                                 & ~((bfd_size_type) per_width - 1)));
980                     buf += per_width;
981                     break;
982                   case 'R':
983                     if (action & 1)
984                       {
985                         BFD_ASSERT (*buf == sec_info->entry[i].fde_encoding);
986                         *buf |= DW_EH_PE_pcrel;
987                         action &= ~1;
988                       }
989                     buf++;
990                     break;
991                   default:
992                     BFD_FAIL ();
993                   }
994             }
995         }
996       else
997         {
998           /* FDE */
999           bfd_vma value = 0, address;
1000           unsigned int width;
1001
1002           buf = contents + sec_info->entry[i].offset;
1003           /* Skip length.  */   
1004           buf += 4;
1005           bfd_put_32 (abfd,
1006                       sec_info->entry[i].new_offset + 4 - cie_offset, buf);
1007           buf += 4;
1008           width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding,
1009                                       ptr_size);
1010           address = value = read_value (abfd, buf, width);
1011           if (value)
1012             {
1013               switch (sec_info->entry[i].fde_encoding & 0xf0)
1014                 {
1015                 case DW_EH_PE_indirect:
1016                 case DW_EH_PE_textrel:
1017                   BFD_ASSERT (hdr_info == NULL);
1018                   break;
1019                 case DW_EH_PE_datarel:
1020                   {
1021                     asection *got = bfd_get_section_by_name (abfd, ".got");
1022
1023                     BFD_ASSERT (got != NULL);
1024                     address += got->vma;
1025                   }
1026                   break;
1027                 case DW_EH_PE_pcrel:
1028                   value += (sec_info->entry[i].offset
1029                             - sec_info->entry[i].new_offset);
1030                   address += (sec->output_section->vma + sec->output_offset
1031                               + sec_info->entry[i].offset + 8);
1032                   break;
1033                 }
1034               if (sec_info->entry[i].make_relative)
1035                 value -= (sec->output_section->vma + sec->output_offset
1036                           + sec_info->entry[i].new_offset + 8);
1037               write_value (abfd, buf, value, width);
1038             }
1039
1040           if (hdr_info)
1041             {
1042               hdr_info->array[hdr_info->array_count].initial_loc = address;
1043               hdr_info->array[hdr_info->array_count++].fde
1044                 = (sec->output_section->vma + sec->output_offset
1045                    + sec_info->entry[i].new_offset);
1046             }
1047
1048           if ((sec_info->entry[i].lsda_encoding & 0xf0) == DW_EH_PE_pcrel
1049               || sec_info->entry[i].make_lsda_relative)
1050             {
1051               buf += sec_info->entry[i].lsda_offset;
1052               width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding,
1053                                           ptr_size);
1054               value = read_value (abfd, buf, width);
1055               if (value)
1056                 {
1057                   if ((sec_info->entry[i].lsda_encoding & 0xf0)
1058                       == DW_EH_PE_pcrel)
1059                     value += (sec_info->entry[i].offset
1060                               - sec_info->entry[i].new_offset);
1061                   else if (sec_info->entry[i].make_lsda_relative)
1062                     value -= (sec->output_section->vma + sec->output_offset
1063                               + sec_info->entry[i].new_offset + 8
1064                               + sec_info->entry[i].lsda_offset);
1065                   write_value (abfd, buf, value, width);
1066                 }
1067             }
1068         }
1069
1070       BFD_ASSERT (p == contents + sec_info->entry[i].new_offset);
1071       memmove (p, contents + sec_info->entry[i].offset,
1072                sec_info->entry[i].size);
1073       p += sec_info->entry[i].size;
1074     }
1075
1076   /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
1077      shrink sections to zero size, this won't be needed any more.  */
1078   if (p == contents && sec->_cooked_size == 16)
1079     {
1080       bfd_put_32 (abfd, 12, p);         /* Fake CIE length */
1081       bfd_put_32 (abfd, 0, p + 4);      /* Fake CIE id */
1082       p[8] = 1;                         /* Fake CIE version */
1083       memset (p + 9, 0, 7);             /* Fake CIE augmentation, 3xleb128
1084                                            and 3xDW_CFA_nop as pad  */
1085       p += 16;
1086     }
1087
1088   BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);
1089
1090   return bfd_set_section_contents (abfd, sec->output_section,
1091                                    contents, (file_ptr) sec->output_offset,
1092                                    sec->_cooked_size);
1093 }
1094
1095 /* Helper function used to sort .eh_frame_hdr search table by increasing
1096    VMA of FDE initial location.  */
1097
1098 static int
1099 vma_compare (a, b)
1100      const PTR a;
1101      const PTR b;
1102 {
1103   struct eh_frame_array_ent *p = (struct eh_frame_array_ent *) a;
1104   struct eh_frame_array_ent *q = (struct eh_frame_array_ent *) b;
1105   if (p->initial_loc > q->initial_loc)
1106     return 1;
1107   if (p->initial_loc < q->initial_loc)
1108     return -1;
1109   return 0;
1110 }
1111
1112 /* Write out .eh_frame_hdr section.  This must be called after
1113    _bfd_elf_write_section_eh_frame has been called on all input
1114    .eh_frame sections.
1115    .eh_frame_hdr format:
1116    ubyte version                (currently 1)
1117    ubyte eh_frame_ptr_enc       (DW_EH_PE_* encoding of pointer to start of
1118                                  .eh_frame section)
1119    ubyte fde_count_enc          (DW_EH_PE_* encoding of total FDE count
1120                                  number (or DW_EH_PE_omit if there is no
1121                                  binary search table computed))
1122    ubyte table_enc              (DW_EH_PE_* encoding of binary search table,
1123                                  or DW_EH_PE_omit if not present.
1124                                  DW_EH_PE_datarel is using address of
1125                                  .eh_frame_hdr section start as base)
1126    [encoded] eh_frame_ptr       (pointer to start of .eh_frame section)
1127    optionally followed by:
1128    [encoded] fde_count          (total number of FDEs in .eh_frame section)
1129    fde_count x [encoded] initial_loc, fde
1130                                 (array of encoded pairs containing
1131                                  FDE initial_location field and FDE address,
1132                                  sorted by increasing initial_loc)  */
1133
1134 boolean
1135 _bfd_elf_write_section_eh_frame_hdr (abfd, sec)
1136      bfd *abfd;
1137      asection *sec;
1138 {
1139   struct eh_frame_hdr_info *hdr_info;
1140   unsigned int ptr_size;
1141   bfd_byte *contents;
1142   asection *eh_frame_sec;
1143   bfd_size_type size;
1144
1145   ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
1146               == ELFCLASS64) ? 8 : 4;
1147
1148   BFD_ASSERT (elf_section_data (sec)->sec_info_type
1149               == ELF_INFO_TYPE_EH_FRAME_HDR);
1150   hdr_info = (struct eh_frame_hdr_info *)
1151              elf_section_data (sec)->sec_info;
1152   size = EH_FRAME_HDR_SIZE;
1153   if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1154     size += 4 + hdr_info->fde_count * 8;
1155   contents = bfd_malloc (size);
1156   if (contents == NULL)
1157     return false;
1158
1159   eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
1160   if (eh_frame_sec == NULL)
1161     return false;
1162
1163   memset (contents, 0, EH_FRAME_HDR_SIZE);
1164   contents[0] = 1;                              /* Version  */
1165   contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset  */
1166   if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1167     {
1168       contents[2] = DW_EH_PE_udata4;            /* FDE count encoding  */
1169       contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* search table enc  */
1170     }
1171   else
1172     {
1173       contents[2] = DW_EH_PE_omit;
1174       contents[3] = DW_EH_PE_omit;
1175     }
1176   bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
1177               contents + 4);
1178   if (contents[2] != DW_EH_PE_omit)
1179     {
1180       unsigned int i;
1181
1182       bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
1183       qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
1184              vma_compare);
1185       for (i = 0; i < hdr_info->fde_count; i++)
1186         {
1187           bfd_put_32 (abfd,
1188                       hdr_info->array[i].initial_loc
1189                       - sec->output_section->vma,
1190                       contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
1191           bfd_put_32 (abfd,
1192                       hdr_info->array[i].fde - sec->output_section->vma,
1193                       contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
1194         }
1195     }
1196
1197   return bfd_set_section_contents (abfd, sec->output_section,
1198                                    contents, (file_ptr) sec->output_offset,
1199                                    sec->_cooked_size);
1200 }