OSDN Git Service

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