2002-10-31 David O'Brien <obrien@FreeBSD.org>
[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   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) PARAMS ((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 ((bfd_size_type) (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           /* Note - in DWARF2 the return address column is an unsigned byte.
510              In DWARF3 it is a ULEB128.  We are following DWARF3.  For most
511              ports this will not matter as the value will be less than 128.
512              For the others (eg FRV, SH, MMIX, IA64) they need a fixed GCC
513              which conforms to the DWARF3 standard.  */
514           read_uleb128 (cie.ra_column, buf);
515           ENSURE_NO_RELOCS (buf);
516           cie.lsda_encoding = DW_EH_PE_omit;
517           cie.fde_encoding = DW_EH_PE_omit;
518           cie.per_encoding = DW_EH_PE_omit;
519           aug = cie.augmentation;
520           if (aug[0] != 'e' || aug[1] != 'h')
521             {
522               if (*aug == 'z')
523                 {
524                   aug++;
525                   read_uleb128 (cie.augmentation_size, buf);
526                   ENSURE_NO_RELOCS (buf);
527                 }
528
529               while (*aug != '\0')
530                 switch (*aug++)
531                   {
532                   case 'L':
533                     cie.lsda_encoding = *buf++;
534                     ENSURE_NO_RELOCS (buf);
535                     if (get_DW_EH_PE_width (cie.lsda_encoding, ptr_size) == 0)
536                       goto free_no_table;
537                     break;
538                   case 'R':
539                     cie.fde_encoding = *buf++;
540                     ENSURE_NO_RELOCS (buf);
541                     if (get_DW_EH_PE_width (cie.fde_encoding, ptr_size) == 0)
542                       goto free_no_table;
543                     break;
544                   case 'P':
545                     {
546                       int per_width;
547
548                       cie.per_encoding = *buf++;
549                       per_width = get_DW_EH_PE_width (cie.per_encoding,
550                                                       ptr_size);
551                       if (per_width == 0)
552                         goto free_no_table;
553                       if ((cie.per_encoding & 0xf0) == DW_EH_PE_aligned)
554                         buf = (ehbuf
555                                + ((buf - ehbuf + per_width - 1)
556                                   & ~((bfd_size_type) per_width - 1)));
557                       ENSURE_NO_RELOCS (buf);
558                       rel = GET_RELOC (buf);
559                       /* Ensure we have a reloc here, against
560                          a global symbol.  */
561                       if (rel != NULL)
562                         {
563                           unsigned long r_symndx;
564
565 #ifdef BFD64
566                           if (ptr_size == 8)
567                             r_symndx = ELF64_R_SYM (cookie->rel->r_info);
568                           else
569 #endif
570                             r_symndx = ELF32_R_SYM (cookie->rel->r_info);
571                           if (r_symndx >= cookie->locsymcount)
572                             {
573                               struct elf_link_hash_entry *h;
574
575                               r_symndx -= cookie->extsymoff;
576                               h = cookie->sym_hashes[r_symndx];
577
578                               while (h->root.type == bfd_link_hash_indirect
579                                      || h->root.type == bfd_link_hash_warning)
580                                 h = (struct elf_link_hash_entry *)
581                                     h->root.u.i.link;
582
583                               cie.personality = h;
584                             }
585                           cookie->rel++;
586                         }
587                       buf += per_width;
588                     }
589                     break;
590                   default:
591                     /* Unrecognized augmentation. Better bail out.  */
592                     goto free_no_table;
593                   }
594             }
595
596           /* For shared libraries, try to get rid of as many RELATIVE relocs
597              as possible.  */
598           if (info->shared
599               && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
600             cie.make_relative = 1;
601
602           if (info->shared
603               && (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
604             cie.make_lsda_relative = 1;
605
606           /* If FDE encoding was not specified, it defaults to
607              DW_EH_absptr.  */
608           if (cie.fde_encoding == DW_EH_PE_omit)
609             cie.fde_encoding = DW_EH_PE_absptr;
610
611           initial_insn_length = cie.hdr.length - (buf - last_fde - 4);
612           if (initial_insn_length <= 50)
613             {
614               cie.initial_insn_length = initial_insn_length;
615               memcpy (cie.initial_instructions, buf, initial_insn_length);
616             }
617           buf += initial_insn_length;
618           ENSURE_NO_RELOCS (buf);
619           last_cie = last_fde;
620         }
621       else
622         {
623           /* Ensure this FDE uses the last CIE encountered.  */
624           if (last_cie == NULL
625               || hdr.id != (unsigned int) (buf - 4 - last_cie))
626             goto free_no_table;
627
628           ENSURE_NO_RELOCS (buf);
629           rel = GET_RELOC (buf);
630           if (rel == NULL)
631             /* This should not happen.  */
632             goto free_no_table;
633           if ((*reloc_symbol_deleted_p) (buf - ehbuf, cookie))
634             {
635               /* This is a FDE against discarded section, it should
636                  be deleted.  */
637               new_size -= hdr.length + 4;
638               sec_info->entry[sec_info->count].removed = 1;
639               memset (rel, 0, sizeof (*rel));
640             }
641           else
642             {
643               if (info->shared
644                   && (((cie.fde_encoding & 0xf0) == DW_EH_PE_absptr
645                        && cie.make_relative == 0)
646                       || (cie.fde_encoding & 0xf0) == DW_EH_PE_aligned))
647                 {
648                   /* If shared library uses absolute pointers
649                      which we cannot turn into PC relative,
650                      don't create the binary search table,
651                      since it is affected by runtime relocations.  */
652                   hdr_info->table = false;
653                 }
654               cie_usage_count++;
655               hdr_info->fde_count++;
656             }
657           cookie->rel = rel;
658           if (cie.lsda_encoding != DW_EH_PE_omit)
659             {
660               unsigned int dummy;
661
662               aug = buf;
663               buf += 2 * get_DW_EH_PE_width (cie.fde_encoding, ptr_size);
664               if (cie.augmentation[0] == 'z')
665                 read_uleb128 (dummy, buf);
666               /* If some new augmentation data is added before LSDA
667                  in FDE augmentation area, this need to be adjusted.  */
668               sec_info->entry[sec_info->count].lsda_offset = (buf - aug);
669             }
670           buf = last_fde + 4 + hdr.length;
671           SKIP_RELOCS (buf);
672         }
673
674       sec_info->entry[sec_info->count].fde_encoding = cie.fde_encoding;
675       sec_info->entry[sec_info->count].lsda_encoding = cie.lsda_encoding;
676       sec_info->count++;
677     }
678
679   elf_section_data (sec)->sec_info = sec_info;
680   elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
681
682   /* Ok, now we can assign new offsets.  */
683   offset = 0;
684   last_cie_ndx = 0;
685   for (i = 0; i < sec_info->count; i++)
686     {
687       if (! sec_info->entry[i].removed)
688         {
689           sec_info->entry[i].new_offset = offset;
690           offset += sec_info->entry[i].size;
691           if (sec_info->entry[i].cie)
692             {
693               last_cie_ndx = i;
694               make_relative = sec_info->entry[i].make_relative;
695               make_lsda_relative = sec_info->entry[i].make_lsda_relative;
696             }
697           else
698             {
699               sec_info->entry[i].make_relative = make_relative;
700               sec_info->entry[i].make_lsda_relative = make_lsda_relative;
701               sec_info->entry[i].per_encoding_relative = 0;
702             }
703         }
704       else if (sec_info->entry[i].cie && sec_info->entry[i].sec == sec)
705         {
706           /* Need to adjust new_offset too.  */
707           BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
708                       == sec_info->entry[i].new_offset);
709           sec_info->entry[i].new_offset
710             = sec_info->entry[last_cie_ndx].new_offset;
711         }
712     }
713   if (hdr_info->last_cie_sec == sec)
714     {
715       BFD_ASSERT (sec_info->entry[last_cie_ndx].offset
716                   == hdr_info->last_cie_offset);
717       hdr_info->last_cie_offset = sec_info->entry[last_cie_ndx].new_offset;
718     }
719
720   /* FIXME: Currently it is not possible to shrink sections to zero size at
721      this point, so build a fake minimal CIE.  */
722   if (new_size == 0)
723     new_size = 16;
724
725   /* Shrink the sec as needed.  */
726   sec->_cooked_size = new_size;
727   if (sec->_cooked_size == 0)
728     sec->flags |= SEC_EXCLUDE;
729
730   free (ehbuf);
731   return new_size != sec->_raw_size;
732
733 free_no_table:
734   if (ehbuf)
735     free (ehbuf);
736   if (sec_info)
737     free (sec_info);
738   hdr_info->table = false;
739   hdr_info->last_cie.hdr.length = 0;
740   return false;
741 }
742
743 /* This function is called for .eh_frame_hdr section after
744    _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
745    input sections.  It finalizes the size of .eh_frame_hdr section.  */
746
747 boolean
748 _bfd_elf_discard_section_eh_frame_hdr (abfd, info, sec)
749      bfd *abfd;
750      struct bfd_link_info *info;
751      asection *sec;
752 {
753   struct eh_frame_hdr_info *hdr_info;
754   unsigned int ptr_size;
755
756   ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
757               == ELFCLASS64) ? 8 : 4;
758
759   if ((elf_section_data (sec)->sec_info_type
760        != ELF_INFO_TYPE_EH_FRAME_HDR)
761       || ! info->eh_frame_hdr)
762     {
763       _bfd_strip_section_from_output (info, sec);
764       return false;
765     }
766
767   hdr_info = (struct eh_frame_hdr_info *)
768              elf_section_data (sec)->sec_info;
769   if (hdr_info->strip)
770     return false;
771   sec->_cooked_size = EH_FRAME_HDR_SIZE;
772   if (hdr_info->table)
773     sec->_cooked_size += 4 + hdr_info->fde_count * 8;
774
775   /* Request program headers to be recalculated.  */
776   elf_tdata (abfd)->program_header_size = 0;
777   elf_tdata (abfd)->eh_frame_hdr = true;
778   return true;
779 }
780
781 /* This function is called from size_dynamic_sections.
782    It needs to decide whether .eh_frame_hdr should be output or not,
783    because later on it is too late for calling _bfd_strip_section_from_output,
784    since dynamic symbol table has been sized.  */
785
786 boolean
787 _bfd_elf_maybe_strip_eh_frame_hdr (info)
788      struct bfd_link_info *info;
789 {
790   asection *sec, *o;
791   bfd *abfd;
792   struct eh_frame_hdr_info *hdr_info;
793
794   sec = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".eh_frame_hdr");
795   if (sec == NULL || bfd_is_abs_section (sec->output_section))
796     return true;
797
798   hdr_info
799     = bfd_zmalloc (sizeof (struct eh_frame_hdr_info));
800   if (hdr_info == NULL)
801     return false;
802
803   elf_section_data (sec)->sec_info = hdr_info;
804   elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME_HDR;
805
806   abfd = NULL;
807   if (info->eh_frame_hdr)
808     for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
809       {
810         /* Count only sections which have at least a single CIE or FDE.
811            There cannot be any CIE or FDE <= 8 bytes.  */
812         o = bfd_get_section_by_name (abfd, ".eh_frame");
813         if (o && o->_raw_size > 8 && !bfd_is_abs_section (o->output_section))
814           break;
815       }
816
817   if (abfd == NULL)
818     {
819       _bfd_strip_section_from_output (info, sec);
820       hdr_info->strip = true;
821     }
822   else
823     hdr_info->table = true;
824   return true;
825 }
826
827 /* Adjust an address in the .eh_frame section.  Given OFFSET within
828    SEC, this returns the new offset in the adjusted .eh_frame section,
829    or -1 if the address refers to a CIE/FDE which has been removed
830    or to offset with dynamic relocation which is no longer needed.  */
831
832 bfd_vma
833 _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
834      bfd *output_bfd ATTRIBUTE_UNUSED;
835      asection *sec;
836      bfd_vma offset;
837 {
838   struct eh_frame_sec_info *sec_info;
839   unsigned int lo, hi, mid;
840
841   if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
842     return offset;
843   sec_info = (struct eh_frame_sec_info *)
844              elf_section_data (sec)->sec_info;
845
846   if (offset >= sec->_raw_size)
847     return offset - (sec->_cooked_size - sec->_raw_size);
848
849   lo = 0;
850   hi = sec_info->count;
851   mid = 0;
852   while (lo < hi)
853     {
854       mid = (lo + hi) / 2;
855       if (offset < sec_info->entry[mid].offset)
856         hi = mid;
857       else if (offset
858                >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
859         lo = mid + 1;
860       else
861         break;
862     }
863
864   BFD_ASSERT (lo < hi);
865
866   /* FDE or CIE was removed.  */
867   if (sec_info->entry[mid].removed)
868     return (bfd_vma) -1;
869
870   /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
871      relocation against FDE's initial_location field.  */
872   if (sec_info->entry[mid].make_relative
873       && ! sec_info->entry[mid].cie
874       && offset == sec_info->entry[mid].offset + 8)
875     return (bfd_vma) -2;
876
877   /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
878      for run-time relocation against LSDA field.  */
879   if (sec_info->entry[mid].make_lsda_relative
880       && ! sec_info->entry[mid].cie
881       && (offset
882           == (sec_info->entry[mid].offset + 8
883               + sec_info->entry[mid].lsda_offset)))
884     return (bfd_vma) -2;
885
886   return (offset + sec_info->entry[mid].new_offset
887           - sec_info->entry[mid].offset);
888 }
889
890 /* Write out .eh_frame section.  This is called with the relocated
891    contents.  */
892
893 boolean
894 _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
895      bfd *abfd;
896      asection *sec, *ehdrsec;
897      bfd_byte *contents;
898 {
899   struct eh_frame_sec_info *sec_info;
900   struct eh_frame_hdr_info *hdr_info;
901   unsigned int i;
902   bfd_byte *p, *buf;
903   unsigned int leb128_tmp;
904   unsigned int cie_offset = 0;
905   unsigned int ptr_size;
906
907   ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
908               == ELFCLASS64) ? 8 : 4;
909
910   if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
911     return bfd_set_section_contents (abfd, sec->output_section,
912                                      contents,
913                                      (file_ptr) sec->output_offset,
914                                      sec->_raw_size);
915   sec_info = (struct eh_frame_sec_info *)
916              elf_section_data (sec)->sec_info;
917   hdr_info = NULL;
918   if (ehdrsec
919       && (elf_section_data (ehdrsec)->sec_info_type
920           == ELF_INFO_TYPE_EH_FRAME_HDR))
921     {
922       hdr_info = (struct eh_frame_hdr_info *)
923                  elf_section_data (ehdrsec)->sec_info;
924       if (hdr_info->table && hdr_info->array == NULL)
925         hdr_info->array
926           = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
927       if (hdr_info->array == NULL)
928         hdr_info = NULL;
929     }
930
931   p = contents;
932   for (i = 0; i < sec_info->count; ++i)
933     {
934       if (sec_info->entry[i].removed)
935         {
936           if (sec_info->entry[i].cie)
937             {
938               /* If CIE is removed due to no remaining FDEs referencing it
939                  and there were no CIEs kept before it, sec_info->entry[i].sec
940                  will be zero.  */
941               if (sec_info->entry[i].sec == NULL)
942                 cie_offset = 0;
943               else
944                 {
945                   cie_offset = sec_info->entry[i].new_offset;
946                   cie_offset += (sec_info->entry[i].sec->output_section->vma
947                                  + sec_info->entry[i].sec->output_offset
948                                  - sec->output_section->vma
949                                  - sec->output_offset);
950                 }
951             }
952           continue;
953         }
954
955       if (sec_info->entry[i].cie)
956         {
957           /* CIE */
958           cie_offset = sec_info->entry[i].new_offset;
959           if (sec_info->entry[i].make_relative
960               || sec_info->entry[i].make_lsda_relative
961               || sec_info->entry[i].per_encoding_relative)
962             {
963               unsigned char *aug;
964               unsigned int action;
965               unsigned int dummy, per_width, per_encoding;
966
967               /* Need to find 'R' or 'L' augmentation's argument and modify
968                  DW_EH_PE_* value.  */
969               action = (sec_info->entry[i].make_relative ? 1 : 0)
970                        | (sec_info->entry[i].make_lsda_relative ? 2 : 0)
971                        | (sec_info->entry[i].per_encoding_relative ? 4 : 0);
972               buf = contents + sec_info->entry[i].offset;
973               /* Skip length, id and version.  */
974               buf += 9;
975               aug = buf;
976               buf = strchr (buf, '\0') + 1;
977               read_uleb128 (dummy, buf);
978               read_sleb128 (dummy, buf);
979               read_uleb128 (dummy, buf);
980               if (*aug == 'z')
981                 {
982                   read_uleb128 (dummy, buf);
983                   aug++;
984                 }
985
986               while (action)
987                 switch (*aug++)
988                   {
989                   case 'L':
990                     if (action & 2)
991                       {
992                         BFD_ASSERT (*buf == sec_info->entry[i].lsda_encoding);
993                         *buf |= DW_EH_PE_pcrel;
994                         action &= ~2;
995                       }
996                     buf++;
997                     break;
998                   case 'P':
999                     per_encoding = *buf++;
1000                     per_width = get_DW_EH_PE_width (per_encoding,
1001                                                     ptr_size);
1002                     BFD_ASSERT (per_width != 0);
1003                     BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
1004                                 == sec_info->entry[i].per_encoding_relative);
1005                     if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
1006                       buf = (contents
1007                              + ((buf - contents + per_width - 1)
1008                                 & ~((bfd_size_type) per_width - 1)));
1009                     if (action & 4)
1010                       {
1011                         bfd_vma value;
1012
1013                         value = read_value (abfd, buf, per_width);
1014                         value += (sec_info->entry[i].offset
1015                                   - sec_info->entry[i].new_offset);
1016                         write_value (abfd, buf, value, per_width);
1017                         action &= ~4;
1018                       }
1019                     buf += per_width;
1020                     break;
1021                   case 'R':
1022                     if (action & 1)
1023                       {
1024                         BFD_ASSERT (*buf == sec_info->entry[i].fde_encoding);
1025                         *buf |= DW_EH_PE_pcrel;
1026                         action &= ~1;
1027                       }
1028                     buf++;
1029                     break;
1030                   default:
1031                     BFD_FAIL ();
1032                   }
1033             }
1034         }
1035       else if (sec_info->entry[i].size > 4)
1036         {
1037           /* FDE */
1038           bfd_vma value = 0, address;
1039           unsigned int width;
1040
1041           buf = contents + sec_info->entry[i].offset;
1042           /* Skip length.  */   
1043           buf += 4;
1044           bfd_put_32 (abfd,
1045                       sec_info->entry[i].new_offset + 4 - cie_offset, buf);
1046           buf += 4;
1047           width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding,
1048                                       ptr_size);
1049           address = value = read_value (abfd, buf, width);
1050           if (value)
1051             {
1052               switch (sec_info->entry[i].fde_encoding & 0xf0)
1053                 {
1054                 case DW_EH_PE_indirect:
1055                 case DW_EH_PE_textrel:
1056                   BFD_ASSERT (hdr_info == NULL);
1057                   break;
1058                 case DW_EH_PE_datarel:
1059                   {
1060                     asection *got = bfd_get_section_by_name (abfd, ".got");
1061
1062                     BFD_ASSERT (got != NULL);
1063                     address += got->vma;
1064                   }
1065                   break;
1066                 case DW_EH_PE_pcrel:
1067                   value += (sec_info->entry[i].offset
1068                             - sec_info->entry[i].new_offset);
1069                   address += (sec->output_section->vma + sec->output_offset
1070                               + sec_info->entry[i].offset + 8);
1071                   break;
1072                 }
1073               if (sec_info->entry[i].make_relative)
1074                 value -= (sec->output_section->vma + sec->output_offset
1075                           + sec_info->entry[i].new_offset + 8);
1076               write_value (abfd, buf, value, width);
1077             }
1078
1079           if (hdr_info)
1080             {
1081               hdr_info->array[hdr_info->array_count].initial_loc = address;
1082               hdr_info->array[hdr_info->array_count++].fde
1083                 = (sec->output_section->vma + sec->output_offset
1084                    + sec_info->entry[i].new_offset);
1085             }
1086
1087           if ((sec_info->entry[i].lsda_encoding & 0xf0) == DW_EH_PE_pcrel
1088               || sec_info->entry[i].make_lsda_relative)
1089             {
1090               buf += sec_info->entry[i].lsda_offset;
1091               width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding,
1092                                           ptr_size);
1093               value = read_value (abfd, buf, width);
1094               if (value)
1095                 {
1096                   if ((sec_info->entry[i].lsda_encoding & 0xf0)
1097                       == DW_EH_PE_pcrel)
1098                     value += (sec_info->entry[i].offset
1099                               - sec_info->entry[i].new_offset);
1100                   else if (sec_info->entry[i].make_lsda_relative)
1101                     value -= (sec->output_section->vma + sec->output_offset
1102                               + sec_info->entry[i].new_offset + 8
1103                               + sec_info->entry[i].lsda_offset);
1104                   write_value (abfd, buf, value, width);
1105                 }
1106             }
1107         }
1108       else
1109         /* Terminating FDE must be at the end of .eh_frame section only.  */
1110         BFD_ASSERT (i == sec_info->count - 1);
1111
1112       BFD_ASSERT (p == contents + sec_info->entry[i].new_offset);
1113       memmove (p, contents + sec_info->entry[i].offset,
1114                sec_info->entry[i].size);
1115       p += sec_info->entry[i].size;
1116     }
1117
1118   /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
1119      shrink sections to zero size, this won't be needed any more.  */
1120   if (p == contents && sec->_cooked_size == 16)
1121     {
1122       bfd_put_32 (abfd, 12, p);         /* Fake CIE length */
1123       bfd_put_32 (abfd, 0, p + 4);      /* Fake CIE id */
1124       p[8] = 1;                         /* Fake CIE version */
1125       memset (p + 9, 0, 7);             /* Fake CIE augmentation, 3xleb128
1126                                            and 3xDW_CFA_nop as pad  */
1127       p += 16;
1128     }
1129
1130   BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);
1131
1132   return bfd_set_section_contents (abfd, sec->output_section,
1133                                    contents, (file_ptr) sec->output_offset,
1134                                    sec->_cooked_size);
1135 }
1136
1137 /* Helper function used to sort .eh_frame_hdr search table by increasing
1138    VMA of FDE initial location.  */
1139
1140 static int
1141 vma_compare (a, b)
1142      const PTR a;
1143      const PTR b;
1144 {
1145   struct eh_frame_array_ent *p = (struct eh_frame_array_ent *) a;
1146   struct eh_frame_array_ent *q = (struct eh_frame_array_ent *) b;
1147   if (p->initial_loc > q->initial_loc)
1148     return 1;
1149   if (p->initial_loc < q->initial_loc)
1150     return -1;
1151   return 0;
1152 }
1153
1154 /* Write out .eh_frame_hdr section.  This must be called after
1155    _bfd_elf_write_section_eh_frame has been called on all input
1156    .eh_frame sections.
1157    .eh_frame_hdr format:
1158    ubyte version                (currently 1)
1159    ubyte eh_frame_ptr_enc       (DW_EH_PE_* encoding of pointer to start of
1160                                  .eh_frame section)
1161    ubyte fde_count_enc          (DW_EH_PE_* encoding of total FDE count
1162                                  number (or DW_EH_PE_omit if there is no
1163                                  binary search table computed))
1164    ubyte table_enc              (DW_EH_PE_* encoding of binary search table,
1165                                  or DW_EH_PE_omit if not present.
1166                                  DW_EH_PE_datarel is using address of
1167                                  .eh_frame_hdr section start as base)
1168    [encoded] eh_frame_ptr       (pointer to start of .eh_frame section)
1169    optionally followed by:
1170    [encoded] fde_count          (total number of FDEs in .eh_frame section)
1171    fde_count x [encoded] initial_loc, fde
1172                                 (array of encoded pairs containing
1173                                  FDE initial_location field and FDE address,
1174                                  sorted by increasing initial_loc)  */
1175
1176 boolean
1177 _bfd_elf_write_section_eh_frame_hdr (abfd, sec)
1178      bfd *abfd;
1179      asection *sec;
1180 {
1181   struct eh_frame_hdr_info *hdr_info;
1182   unsigned int ptr_size;
1183   bfd_byte *contents;
1184   asection *eh_frame_sec;
1185   bfd_size_type size;
1186
1187   ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
1188               == ELFCLASS64) ? 8 : 4;
1189
1190   BFD_ASSERT (elf_section_data (sec)->sec_info_type
1191               == ELF_INFO_TYPE_EH_FRAME_HDR);
1192   hdr_info = (struct eh_frame_hdr_info *)
1193              elf_section_data (sec)->sec_info;
1194   if (hdr_info->strip)
1195     return true;
1196
1197   size = EH_FRAME_HDR_SIZE;
1198   if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1199     size += 4 + hdr_info->fde_count * 8;
1200   contents = bfd_malloc (size);
1201   if (contents == NULL)
1202     return false;
1203
1204   eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
1205   if (eh_frame_sec == NULL)
1206     return false;
1207
1208   memset (contents, 0, EH_FRAME_HDR_SIZE);
1209   contents[0] = 1;                              /* Version  */
1210   contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset  */
1211   if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1212     {
1213       contents[2] = DW_EH_PE_udata4;            /* FDE count encoding  */
1214       contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* search table enc  */
1215     }
1216   else
1217     {
1218       contents[2] = DW_EH_PE_omit;
1219       contents[3] = DW_EH_PE_omit;
1220     }
1221   bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
1222               contents + 4);
1223   if (contents[2] != DW_EH_PE_omit)
1224     {
1225       unsigned int i;
1226
1227       bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
1228       qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
1229              vma_compare);
1230       for (i = 0; i < hdr_info->fde_count; i++)
1231         {
1232           bfd_put_32 (abfd,
1233                       hdr_info->array[i].initial_loc
1234                       - sec->output_section->vma,
1235                       contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
1236           bfd_put_32 (abfd,
1237                       hdr_info->array[i].fde - sec->output_section->vma,
1238                       contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
1239         }
1240     }
1241
1242   return bfd_set_section_contents (abfd, sec->output_section,
1243                                    contents, (file_ptr) sec->output_offset,
1244                                    sec->_cooked_size);
1245 }