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