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