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