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