elf-eh-frame.c revision 107492
1/* .eh_frame section optimization.
2   Copyright 2001, 2002 Free Software Foundation, Inc.
3   Written by Jakub Jelinek <jakub@redhat.com>.
4
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, 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
29struct cie_header
30{
31  unsigned int length;
32  unsigned int id;
33};
34
35struct 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
54struct 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
70struct eh_frame_sec_info
71{
72  unsigned int count;
73  unsigned int alloced;
74  struct eh_cie_fde entry[1];
75};
76
77struct eh_frame_array_ent
78{
79  bfd_vma initial_loc;
80  bfd_vma fde;
81};
82
83struct 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
97static bfd_vma read_unsigned_leb128
98  PARAMS ((bfd *, char *, unsigned int *));
99static bfd_signed_vma read_signed_leb128
100  PARAMS ((bfd *, char *, unsigned int *));
101static int get_DW_EH_PE_width
102  PARAMS ((int, int));
103static bfd_vma read_value
104  PARAMS ((bfd *, bfd_byte *, int));
105static void write_value
106  PARAMS ((bfd *, bfd_byte *, bfd_vma, int));
107static int cie_compare
108  PARAMS ((struct cie *, struct cie *));
109static int vma_compare
110  PARAMS ((const PTR a, const PTR b));
111
112/* Helper function for reading uleb128 encoded data.  */
113
114static bfd_vma
115read_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
143static bfd_signed_vma
144read_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)					\
173do								\
174  {								\
175    (VAR) = read_unsigned_leb128 (abfd, buf, &leb128_tmp);	\
176    (BUF) += leb128_tmp;					\
177  }								\
178while (0)
179
180#define read_sleb128(VAR, BUF)					\
181do								\
182  {								\
183    (VAR) = read_signed_leb128 (abfd, buf, &leb128_tmp);	\
184    (BUF) += leb128_tmp;					\
185  }								\
186while (0)
187
188/* Return 0 if either encoding is variable width, or not yet known to bfd.  */
189
190static
191int 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
214static bfd_vma
215read_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
235static void
236write_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
253static
254int 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
284boolean
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) (bfd_vma, PTR);
291     struct elf_reloc_cookie *cookie;
292{
293  bfd_byte *ehbuf = NULL, *buf;
294  bfd_byte *last_cie, *last_fde;
295  struct cie_header hdr;
296  struct cie cie;
297  struct eh_frame_hdr_info *hdr_info;
298  struct eh_frame_sec_info *sec_info = NULL;
299  unsigned int leb128_tmp;
300  unsigned int cie_usage_count, last_cie_ndx, i, offset;
301  unsigned int make_relative, make_lsda_relative;
302  Elf_Internal_Rela *rel;
303  bfd_size_type new_size;
304  unsigned int ptr_size;
305
306  if (sec->_raw_size == 0)
307    {
308      /* This file does not contain .eh_frame information.  */
309      return false;
310    }
311
312  if ((sec->output_section != NULL
313       && bfd_is_abs_section (sec->output_section)))
314    {
315      /* At least one of the sections is being discarded from the
316         link, so we should just ignore them.  */
317      return false;
318    }
319
320  BFD_ASSERT (elf_section_data (ehdrsec)->sec_info_type
321	      == ELF_INFO_TYPE_EH_FRAME_HDR);
322  hdr_info = (struct eh_frame_hdr_info *)
323	     elf_section_data (ehdrsec)->sec_info;
324
325  /* Read the frame unwind information from abfd.  */
326
327  ehbuf = (bfd_byte *) bfd_malloc (sec->_raw_size);
328  if (ehbuf == NULL)
329    goto free_no_table;
330
331  if (! bfd_get_section_contents (abfd, sec, ehbuf, (bfd_vma) 0,
332				  sec->_raw_size))
333    goto free_no_table;
334
335  if (sec->_raw_size >= 4
336      && bfd_get_32 (abfd, ehbuf) == 0
337      && cookie->rel == cookie->relend)
338    {
339      /* Empty .eh_frame section.  */
340      free (ehbuf);
341      return false;
342    }
343
344  /* If .eh_frame section size doesn't fit into int, we cannot handle
345     it (it would need to use 64-bit .eh_frame format anyway).  */
346  if (sec->_raw_size != (unsigned int) sec->_raw_size)
347    goto free_no_table;
348
349  ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
350	      == ELFCLASS64) ? 8 : 4;
351  buf = ehbuf;
352  last_cie = NULL;
353  last_cie_ndx = 0;
354  memset (&cie, 0, sizeof (cie));
355  cie_usage_count = 0;
356  new_size = sec->_raw_size;
357  make_relative = hdr_info->last_cie.make_relative;
358  make_lsda_relative = hdr_info->last_cie.make_lsda_relative;
359  sec_info = bfd_zmalloc (sizeof (struct eh_frame_sec_info)
360			  + 99 * sizeof (struct eh_cie_fde));
361  if (sec_info == NULL)
362    goto free_no_table;
363  sec_info->alloced = 100;
364
365#define ENSURE_NO_RELOCS(buf)				\
366  if (cookie->rel < cookie->relend			\
367      && (cookie->rel->r_offset				\
368	  < (bfd_size_type) ((buf) - ehbuf)))		\
369    goto free_no_table
370
371#define SKIP_RELOCS(buf)				\
372  while (cookie->rel < cookie->relend			\
373         && (cookie->rel->r_offset			\
374	     < (bfd_size_type) ((buf) - ehbuf)))	\
375    cookie->rel++
376
377#define GET_RELOC(buf)					\
378  ((cookie->rel < cookie->relend			\
379    && (cookie->rel->r_offset				\
380        == (bfd_size_type) ((buf) - ehbuf)))		\
381   ? cookie->rel : NULL)
382
383  for (;;)
384    {
385      unsigned char *aug;
386
387      if (sec_info->count == sec_info->alloced)
388	{
389	  sec_info = bfd_realloc (sec_info,
390				  sizeof (struct eh_frame_sec_info)
391				  + (sec_info->alloced + 99)
392				     * sizeof (struct eh_cie_fde));
393	  if (sec_info == NULL)
394	    goto free_no_table;
395
396	  memset (&sec_info->entry[sec_info->alloced], 0,
397		  100 * sizeof (struct eh_cie_fde));
398	  sec_info->alloced += 100;
399	}
400
401      last_fde = buf;
402      /* If we are at the end of the section, we still need to decide
403	 on whether to output or discard last encountered CIE (if any).  */
404      if ((bfd_size_type) (buf - ehbuf) == sec->_raw_size)
405	hdr.id = (unsigned int) -1;
406      else
407	{
408	  if ((bfd_size_type) (buf + 4 - ehbuf) > sec->_raw_size)
409	    /* No space for CIE/FDE header length.  */
410	    goto free_no_table;
411
412	  hdr.length = bfd_get_32 (abfd, buf);
413	  if (hdr.length == 0xffffffff)
414	    /* 64-bit .eh_frame is not supported.  */
415	    goto free_no_table;
416	  buf += 4;
417	  if ((bfd_size_type) (buf - ehbuf) + hdr.length > sec->_raw_size)
418	    /* CIE/FDE not contained fully in this .eh_frame input section.  */
419	    goto free_no_table;
420
421	  sec_info->entry[sec_info->count].offset = last_fde - ehbuf;
422	  sec_info->entry[sec_info->count].size = 4 + hdr.length;
423
424	  if (hdr.length == 0)
425	    {
426	      /* CIE with length 0 must be only the last in the section.  */
427	      if ((bfd_size_type) (buf - ehbuf) < sec->_raw_size)
428		goto free_no_table;
429	      ENSURE_NO_RELOCS (buf);
430	      sec_info->count++;
431	      /* Now just finish last encountered CIE processing and break
432		 the loop.  */
433	      hdr.id = (unsigned int) -1;
434	    }
435	  else
436	    {
437	      hdr.id = bfd_get_32 (abfd, buf);
438	      buf += 4;
439	      if (hdr.id == (unsigned int) -1)
440		goto free_no_table;
441	    }
442	}
443
444      if (hdr.id == 0 || hdr.id == (unsigned int) -1)
445	{
446	  unsigned int initial_insn_length;
447
448	  /* CIE  */
449	  if (last_cie != NULL)
450	    {
451	      /* Now check if this CIE is identical to last CIE, in which case
452		 we can remove it, provided we adjust all FDEs.
453		 Also, it can be removed if we have removed all FDEs using
454		 that. */
455	      if (cie_compare (&cie, &hdr_info->last_cie) == 0
456		  || cie_usage_count == 0)
457		{
458		  new_size -= cie.hdr.length + 4;
459		  sec_info->entry[last_cie_ndx].removed = 1;
460		  sec_info->entry[last_cie_ndx].sec = hdr_info->last_cie_sec;
461		  sec_info->entry[last_cie_ndx].new_offset
462		    = hdr_info->last_cie_offset;
463		}
464	      else
465		{
466		  hdr_info->last_cie = cie;
467		  hdr_info->last_cie_sec = sec;
468		  hdr_info->last_cie_offset = last_cie - ehbuf;
469		  sec_info->entry[last_cie_ndx].make_relative
470		    = cie.make_relative;
471		  sec_info->entry[last_cie_ndx].make_lsda_relative
472		    = cie.make_lsda_relative;
473		  sec_info->entry[last_cie_ndx].per_encoding_relative
474		    = (cie.per_encoding & 0x70) == DW_EH_PE_pcrel;
475		}
476	    }
477
478	  if (hdr.id == (unsigned int) -1)
479	    break;
480
481	  last_cie_ndx = sec_info->count;
482	  sec_info->entry[sec_info->count].cie = 1;
483
484	  cie_usage_count = 0;
485	  memset (&cie, 0, sizeof (cie));
486	  cie.hdr = hdr;
487	  cie.version = *buf++;
488
489	  /* Cannot handle unknown versions.  */
490	  if (cie.version != 1)
491	    goto free_no_table;
492	  if (strlen (buf) > sizeof (cie.augmentation) - 1)
493	    goto free_no_table;
494
495	  strcpy (cie.augmentation, buf);
496	  buf = strchr (buf, '\0') + 1;
497	  ENSURE_NO_RELOCS (buf);
498	  if (buf[0] == 'e' && buf[1] == 'h')
499	    {
500	      /* GCC < 3.0 .eh_frame CIE */
501	      /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
502		 is private to each CIE, so we don't need it for anything.
503		 Just skip it.  */
504	      buf += ptr_size;
505	      SKIP_RELOCS (buf);
506	    }
507	  read_uleb128 (cie.code_align, buf);
508	  read_sleb128 (cie.data_align, buf);
509	  read_uleb128 (cie.ra_column, buf);
510	  ENSURE_NO_RELOCS (buf);
511	  cie.lsda_encoding = DW_EH_PE_omit;
512	  cie.fde_encoding = DW_EH_PE_omit;
513	  cie.per_encoding = DW_EH_PE_omit;
514	  aug = cie.augmentation;
515	  if (aug[0] != 'e' || aug[1] != 'h')
516	    {
517	      if (*aug == 'z')
518		{
519		  aug++;
520		  read_uleb128 (cie.augmentation_size, buf);
521	  	  ENSURE_NO_RELOCS (buf);
522		}
523
524	      while (*aug != '\0')
525		switch (*aug++)
526		  {
527		  case 'L':
528		    cie.lsda_encoding = *buf++;
529		    ENSURE_NO_RELOCS (buf);
530		    if (get_DW_EH_PE_width (cie.lsda_encoding, ptr_size) == 0)
531		      goto free_no_table;
532		    break;
533		  case 'R':
534		    cie.fde_encoding = *buf++;
535		    ENSURE_NO_RELOCS (buf);
536		    if (get_DW_EH_PE_width (cie.fde_encoding, ptr_size) == 0)
537		      goto free_no_table;
538		    break;
539		  case 'P':
540		    {
541		      int per_width;
542
543		      cie.per_encoding = *buf++;
544		      per_width = get_DW_EH_PE_width (cie.per_encoding,
545						      ptr_size);
546		      if (per_width == 0)
547			goto free_no_table;
548		      if ((cie.per_encoding & 0xf0) == DW_EH_PE_aligned)
549			buf = (ehbuf
550			       + ((buf - ehbuf + per_width - 1)
551				  & ~((bfd_size_type) per_width - 1)));
552		      ENSURE_NO_RELOCS (buf);
553		      rel = GET_RELOC (buf);
554		      /* Ensure we have a reloc here, against
555			 a global symbol.  */
556		      if (rel != NULL)
557			{
558			  unsigned long r_symndx;
559
560#ifdef BFD64
561			  if (ptr_size == 8)
562			    r_symndx = ELF64_R_SYM (cookie->rel->r_info);
563			  else
564#endif
565			    r_symndx = ELF32_R_SYM (cookie->rel->r_info);
566			  if (r_symndx >= cookie->locsymcount)
567			    {
568			      struct elf_link_hash_entry *h;
569
570			      r_symndx -= cookie->extsymoff;
571			      h = cookie->sym_hashes[r_symndx];
572
573			      while (h->root.type == bfd_link_hash_indirect
574				     || h->root.type == bfd_link_hash_warning)
575				h = (struct elf_link_hash_entry *)
576				    h->root.u.i.link;
577
578			      cie.personality = h;
579			    }
580			  cookie->rel++;
581			}
582		      buf += per_width;
583		    }
584		    break;
585		  default:
586		    /* Unrecognized augmentation. Better bail out.  */
587		    goto free_no_table;
588		  }
589	    }
590
591	  /* For shared libraries, try to get rid of as many RELATIVE relocs
592	     as possible.  */
593          if (info->shared
594	      && (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
595	    cie.make_relative = 1;
596
597	  if (info->shared
598	      && (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
599	    cie.make_lsda_relative = 1;
600
601	  /* If FDE encoding was not specified, it defaults to
602	     DW_EH_absptr.  */
603	  if (cie.fde_encoding == DW_EH_PE_omit)
604	    cie.fde_encoding = DW_EH_PE_absptr;
605
606	  initial_insn_length = cie.hdr.length - (buf - last_fde - 4);
607	  if (initial_insn_length <= 50)
608	    {
609	      cie.initial_insn_length = initial_insn_length;
610	      memcpy (cie.initial_instructions, buf, initial_insn_length);
611	    }
612	  buf += initial_insn_length;
613	  ENSURE_NO_RELOCS (buf);
614	  last_cie = last_fde;
615	}
616      else
617	{
618	  /* Ensure this FDE uses the last CIE encountered.  */
619	  if (last_cie == NULL
620	      || hdr.id != (unsigned int) (buf - 4 - last_cie))
621	    goto free_no_table;
622
623	  ENSURE_NO_RELOCS (buf);
624	  rel = GET_RELOC (buf);
625	  if (rel == NULL)
626	    /* This should not happen.  */
627	    goto free_no_table;
628	  if ((*reloc_symbol_deleted_p) (buf - ehbuf, cookie))
629	    {
630	      /* This is a FDE against discarded section, it should
631		 be deleted.  */
632	      new_size -= hdr.length + 4;
633	      sec_info->entry[sec_info->count].removed = 1;
634	      memset (rel, 0, sizeof (*rel));
635	    }
636	  else
637	    {
638	      if (info->shared
639		  && (((cie.fde_encoding & 0xf0) == DW_EH_PE_absptr
640		       && cie.make_relative == 0)
641		      || (cie.fde_encoding & 0xf0) == DW_EH_PE_aligned))
642		{
643		  /* If shared library uses absolute pointers
644		     which we cannot turn into PC relative,
645		     don't create the binary search table,
646		     since it is affected by runtime relocations.  */
647		  hdr_info->table = false;
648		}
649	      cie_usage_count++;
650	      hdr_info->fde_count++;
651	    }
652	  cookie->rel = rel;
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
728free_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
742boolean
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  unsigned int ptr_size;
750
751  ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
752	      == ELFCLASS64) ? 8 : 4;
753
754  if ((elf_section_data (sec)->sec_info_type
755       != ELF_INFO_TYPE_EH_FRAME_HDR)
756      || ! info->eh_frame_hdr)
757    {
758      _bfd_strip_section_from_output (info, sec);
759      return false;
760    }
761
762  hdr_info = (struct eh_frame_hdr_info *)
763	     elf_section_data (sec)->sec_info;
764  if (hdr_info->strip)
765    return false;
766  sec->_cooked_size = EH_FRAME_HDR_SIZE;
767  if (hdr_info->table)
768    sec->_cooked_size += 4 + hdr_info->fde_count * 8;
769
770  /* Request program headers to be recalculated.  */
771  elf_tdata (abfd)->program_header_size = 0;
772  elf_tdata (abfd)->eh_frame_hdr = true;
773  return true;
774}
775
776/* This function is called from size_dynamic_sections.
777   It needs to decide whether .eh_frame_hdr should be output or not,
778   because later on it is too late for calling _bfd_strip_section_from_output,
779   since dynamic symbol table has been sized.  */
780
781boolean
782_bfd_elf_maybe_strip_eh_frame_hdr (info)
783     struct bfd_link_info *info;
784{
785  asection *sec, *o;
786  bfd *abfd;
787  struct eh_frame_hdr_info *hdr_info;
788
789  sec = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".eh_frame_hdr");
790  if (sec == NULL || bfd_is_abs_section (sec->output_section))
791    return true;
792
793  hdr_info
794    = bfd_zmalloc (sizeof (struct eh_frame_hdr_info));
795  if (hdr_info == NULL)
796    return false;
797
798  elf_section_data (sec)->sec_info = hdr_info;
799  elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME_HDR;
800
801  abfd = NULL;
802  if (info->eh_frame_hdr)
803    for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
804      {
805	/* Count only sections which have at least a single CIE or FDE.
806	   There cannot be any CIE or FDE <= 8 bytes.  */
807	o = bfd_get_section_by_name (abfd, ".eh_frame");
808	if (o && o->_raw_size > 8 && !bfd_is_abs_section (o->output_section))
809	  break;
810      }
811
812  if (abfd == NULL)
813    {
814      _bfd_strip_section_from_output (info, sec);
815      hdr_info->strip = true;
816    }
817  else
818    hdr_info->table = true;
819  return true;
820}
821
822/* Adjust an address in the .eh_frame section.  Given OFFSET within
823   SEC, this returns the new offset in the adjusted .eh_frame section,
824   or -1 if the address refers to a CIE/FDE which has been removed
825   or to offset with dynamic relocation which is no longer needed.  */
826
827bfd_vma
828_bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
829     bfd *output_bfd ATTRIBUTE_UNUSED;
830     asection *sec;
831     bfd_vma offset;
832{
833  struct eh_frame_sec_info *sec_info;
834  unsigned int lo, hi, mid;
835
836  if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
837    return offset;
838  sec_info = (struct eh_frame_sec_info *)
839	     elf_section_data (sec)->sec_info;
840
841  if (offset >= sec->_raw_size)
842    return offset - (sec->_cooked_size - sec->_raw_size);
843
844  lo = 0;
845  hi = sec_info->count;
846  mid = 0;
847  while (lo < hi)
848    {
849      mid = (lo + hi) / 2;
850      if (offset < sec_info->entry[mid].offset)
851	hi = mid;
852      else if (offset
853	       >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
854	lo = mid + 1;
855      else
856	break;
857    }
858
859  BFD_ASSERT (lo < hi);
860
861  /* FDE or CIE was removed.  */
862  if (sec_info->entry[mid].removed)
863    return (bfd_vma) -1;
864
865  /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
866     relocation against FDE's initial_location field.  */
867  if (sec_info->entry[mid].make_relative
868      && ! sec_info->entry[mid].cie
869      && offset == sec_info->entry[mid].offset + 8)
870    return (bfd_vma) -2;
871
872  /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
873     for run-time relocation against LSDA field.  */
874  if (sec_info->entry[mid].make_lsda_relative
875      && ! sec_info->entry[mid].cie
876      && (offset
877	  == (sec_info->entry[mid].offset + 8
878	      + sec_info->entry[mid].lsda_offset)))
879    return (bfd_vma) -2;
880
881  return (offset + sec_info->entry[mid].new_offset
882	  - sec_info->entry[mid].offset);
883}
884
885/* Write out .eh_frame section.  This is called with the relocated
886   contents.  */
887
888boolean
889_bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
890     bfd *abfd;
891     asection *sec, *ehdrsec;
892     bfd_byte *contents;
893{
894  struct eh_frame_sec_info *sec_info;
895  struct eh_frame_hdr_info *hdr_info;
896  unsigned int i;
897  bfd_byte *p, *buf;
898  unsigned int leb128_tmp;
899  unsigned int cie_offset = 0;
900  unsigned int ptr_size;
901
902  ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
903	      == ELFCLASS64) ? 8 : 4;
904
905  if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
906    return bfd_set_section_contents (abfd, sec->output_section,
907				     contents,
908				     (file_ptr) sec->output_offset,
909				     sec->_raw_size);
910  sec_info = (struct eh_frame_sec_info *)
911	     elf_section_data (sec)->sec_info;
912  hdr_info = NULL;
913  if (ehdrsec
914      && (elf_section_data (ehdrsec)->sec_info_type
915	  == ELF_INFO_TYPE_EH_FRAME_HDR))
916    {
917      hdr_info = (struct eh_frame_hdr_info *)
918		 elf_section_data (ehdrsec)->sec_info;
919      if (hdr_info->table && hdr_info->array == NULL)
920	hdr_info->array
921	  = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
922      if (hdr_info->array == NULL)
923        hdr_info = NULL;
924    }
925
926  p = contents;
927  for (i = 0; i < sec_info->count; ++i)
928    {
929      if (sec_info->entry[i].removed)
930	{
931	  if (sec_info->entry[i].cie)
932	    {
933	      /* If CIE is removed due to no remaining FDEs referencing it
934		 and there were no CIEs kept before it, sec_info->entry[i].sec
935		 will be zero.  */
936	      if (sec_info->entry[i].sec == NULL)
937		cie_offset = 0;
938	      else
939		{
940		  cie_offset = sec_info->entry[i].new_offset;
941		  cie_offset += (sec_info->entry[i].sec->output_section->vma
942				 + sec_info->entry[i].sec->output_offset
943				 - sec->output_section->vma
944				 - sec->output_offset);
945		}
946	    }
947	  continue;
948	}
949
950      if (sec_info->entry[i].cie)
951	{
952	  /* CIE */
953	  cie_offset = sec_info->entry[i].new_offset;
954	  if (sec_info->entry[i].make_relative
955	      || sec_info->entry[i].make_lsda_relative
956	      || sec_info->entry[i].per_encoding_relative)
957	    {
958	      unsigned char *aug;
959	      unsigned int action;
960	      unsigned int dummy, per_width, per_encoding;
961
962	      /* Need to find 'R' or 'L' augmentation's argument and modify
963		 DW_EH_PE_* value.  */
964	      action = (sec_info->entry[i].make_relative ? 1 : 0)
965		       | (sec_info->entry[i].make_lsda_relative ? 2 : 0)
966		       | (sec_info->entry[i].per_encoding_relative ? 4 : 0);
967	      buf = contents + sec_info->entry[i].offset;
968	      /* Skip length, id and version.  */
969	      buf += 9;
970	      aug = buf;
971	      buf = strchr (buf, '\0') + 1;
972	      read_uleb128 (dummy, buf);
973	      read_sleb128 (dummy, buf);
974	      read_uleb128 (dummy, buf);
975	      if (*aug == 'z')
976		{
977		  read_uleb128 (dummy, buf);
978		  aug++;
979		}
980
981	      while (action)
982		switch (*aug++)
983		  {
984		  case 'L':
985		    if (action & 2)
986		      {
987			BFD_ASSERT (*buf == sec_info->entry[i].lsda_encoding);
988			*buf |= DW_EH_PE_pcrel;
989			action &= ~2;
990		      }
991		    buf++;
992		    break;
993		  case 'P':
994		    per_encoding = *buf++;
995                    per_width = get_DW_EH_PE_width (per_encoding,
996						    ptr_size);
997		    BFD_ASSERT (per_width != 0);
998		    BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
999				== sec_info->entry[i].per_encoding_relative);
1000		    if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
1001		      buf = (contents
1002			     + ((buf - contents + per_width - 1)
1003				& ~((bfd_size_type) per_width - 1)));
1004		    if (action & 4)
1005		      {
1006			bfd_vma value;
1007
1008			value = read_value (abfd, buf, per_width);
1009			value += (sec_info->entry[i].offset
1010				  - sec_info->entry[i].new_offset);
1011			write_value (abfd, buf, value, per_width);
1012			action &= ~4;
1013		      }
1014		    buf += per_width;
1015		    break;
1016		  case 'R':
1017		    if (action & 1)
1018		      {
1019			BFD_ASSERT (*buf == sec_info->entry[i].fde_encoding);
1020			*buf |= DW_EH_PE_pcrel;
1021			action &= ~1;
1022		      }
1023		    buf++;
1024		    break;
1025		  default:
1026		    BFD_FAIL ();
1027		  }
1028	    }
1029	}
1030      else if (sec_info->entry[i].size > 4)
1031	{
1032	  /* FDE */
1033	  bfd_vma value = 0, address;
1034	  unsigned int width;
1035
1036	  buf = contents + sec_info->entry[i].offset;
1037	  /* Skip length.  */
1038	  buf += 4;
1039	  bfd_put_32 (abfd,
1040		      sec_info->entry[i].new_offset + 4 - cie_offset, buf);
1041	  buf += 4;
1042	  width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding,
1043				      ptr_size);
1044	  address = value = read_value (abfd, buf, width);
1045	  if (value)
1046	    {
1047	      switch (sec_info->entry[i].fde_encoding & 0xf0)
1048		{
1049		case DW_EH_PE_indirect:
1050		case DW_EH_PE_textrel:
1051		  BFD_ASSERT (hdr_info == NULL);
1052		  break;
1053		case DW_EH_PE_datarel:
1054		  {
1055		    asection *got = bfd_get_section_by_name (abfd, ".got");
1056
1057		    BFD_ASSERT (got != NULL);
1058		    address += got->vma;
1059		  }
1060		  break;
1061		case DW_EH_PE_pcrel:
1062		  value += (sec_info->entry[i].offset
1063			    - sec_info->entry[i].new_offset);
1064		  address += (sec->output_section->vma + sec->output_offset
1065			      + sec_info->entry[i].offset + 8);
1066		  break;
1067		}
1068	      if (sec_info->entry[i].make_relative)
1069		value -= (sec->output_section->vma + sec->output_offset
1070			  + sec_info->entry[i].new_offset + 8);
1071	      write_value (abfd, buf, value, width);
1072	    }
1073
1074	  if (hdr_info)
1075	    {
1076	      hdr_info->array[hdr_info->array_count].initial_loc = address;
1077	      hdr_info->array[hdr_info->array_count++].fde
1078		= (sec->output_section->vma + sec->output_offset
1079		   + sec_info->entry[i].new_offset);
1080	    }
1081
1082	  if ((sec_info->entry[i].lsda_encoding & 0xf0) == DW_EH_PE_pcrel
1083	      || sec_info->entry[i].make_lsda_relative)
1084	    {
1085	      buf += sec_info->entry[i].lsda_offset;
1086	      width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding,
1087					  ptr_size);
1088	      value = read_value (abfd, buf, width);
1089	      if (value)
1090		{
1091		  if ((sec_info->entry[i].lsda_encoding & 0xf0)
1092		      == DW_EH_PE_pcrel)
1093		    value += (sec_info->entry[i].offset
1094			      - sec_info->entry[i].new_offset);
1095		  else if (sec_info->entry[i].make_lsda_relative)
1096		    value -= (sec->output_section->vma + sec->output_offset
1097			      + sec_info->entry[i].new_offset + 8
1098			      + sec_info->entry[i].lsda_offset);
1099		  write_value (abfd, buf, value, width);
1100		}
1101	    }
1102	}
1103      else
1104	/* Terminating FDE must be at the end of .eh_frame section only.  */
1105	BFD_ASSERT (i == sec_info->count - 1);
1106
1107      BFD_ASSERT (p == contents + sec_info->entry[i].new_offset);
1108      memmove (p, contents + sec_info->entry[i].offset,
1109	       sec_info->entry[i].size);
1110      p += sec_info->entry[i].size;
1111    }
1112
1113  /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
1114     shrink sections to zero size, this won't be needed any more.  */
1115  if (p == contents && sec->_cooked_size == 16)
1116    {
1117      bfd_put_32 (abfd, 12, p);		/* Fake CIE length */
1118      bfd_put_32 (abfd, 0, p + 4);	/* Fake CIE id */
1119      p[8] = 1;				/* Fake CIE version */
1120      memset (p + 9, 0, 7);		/* Fake CIE augmentation, 3xleb128
1121					   and 3xDW_CFA_nop as pad  */
1122      p += 16;
1123    }
1124
1125  BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);
1126
1127  return bfd_set_section_contents (abfd, sec->output_section,
1128                                   contents, (file_ptr) sec->output_offset,
1129                                   sec->_cooked_size);
1130}
1131
1132/* Helper function used to sort .eh_frame_hdr search table by increasing
1133   VMA of FDE initial location.  */
1134
1135static int
1136vma_compare (a, b)
1137     const PTR a;
1138     const PTR b;
1139{
1140  struct eh_frame_array_ent *p = (struct eh_frame_array_ent *) a;
1141  struct eh_frame_array_ent *q = (struct eh_frame_array_ent *) b;
1142  if (p->initial_loc > q->initial_loc)
1143    return 1;
1144  if (p->initial_loc < q->initial_loc)
1145    return -1;
1146  return 0;
1147}
1148
1149/* Write out .eh_frame_hdr section.  This must be called after
1150   _bfd_elf_write_section_eh_frame has been called on all input
1151   .eh_frame sections.
1152   .eh_frame_hdr format:
1153   ubyte version		(currently 1)
1154   ubyte eh_frame_ptr_enc  	(DW_EH_PE_* encoding of pointer to start of
1155				 .eh_frame section)
1156   ubyte fde_count_enc		(DW_EH_PE_* encoding of total FDE count
1157				 number (or DW_EH_PE_omit if there is no
1158				 binary search table computed))
1159   ubyte table_enc		(DW_EH_PE_* encoding of binary search table,
1160				 or DW_EH_PE_omit if not present.
1161				 DW_EH_PE_datarel is using address of
1162				 .eh_frame_hdr section start as base)
1163   [encoded] eh_frame_ptr	(pointer to start of .eh_frame section)
1164   optionally followed by:
1165   [encoded] fde_count		(total number of FDEs in .eh_frame section)
1166   fde_count x [encoded] initial_loc, fde
1167				(array of encoded pairs containing
1168				 FDE initial_location field and FDE address,
1169				 sorted by increasing initial_loc)  */
1170
1171boolean
1172_bfd_elf_write_section_eh_frame_hdr (abfd, sec)
1173     bfd *abfd;
1174     asection *sec;
1175{
1176  struct eh_frame_hdr_info *hdr_info;
1177  unsigned int ptr_size;
1178  bfd_byte *contents;
1179  asection *eh_frame_sec;
1180  bfd_size_type size;
1181
1182  ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
1183	      == ELFCLASS64) ? 8 : 4;
1184
1185  BFD_ASSERT (elf_section_data (sec)->sec_info_type
1186	      == ELF_INFO_TYPE_EH_FRAME_HDR);
1187  hdr_info = (struct eh_frame_hdr_info *)
1188	     elf_section_data (sec)->sec_info;
1189  if (hdr_info->strip)
1190    return true;
1191
1192  size = EH_FRAME_HDR_SIZE;
1193  if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1194    size += 4 + hdr_info->fde_count * 8;
1195  contents = bfd_malloc (size);
1196  if (contents == NULL)
1197    return false;
1198
1199  eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
1200  if (eh_frame_sec == NULL)
1201    return false;
1202
1203  memset (contents, 0, EH_FRAME_HDR_SIZE);
1204  contents[0] = 1;				/* Version  */
1205  contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset  */
1206  if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
1207    {
1208      contents[2] = DW_EH_PE_udata4;		/* FDE count encoding  */
1209      contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* search table enc  */
1210    }
1211  else
1212    {
1213      contents[2] = DW_EH_PE_omit;
1214      contents[3] = DW_EH_PE_omit;
1215    }
1216  bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
1217	      contents + 4);
1218  if (contents[2] != DW_EH_PE_omit)
1219    {
1220      unsigned int i;
1221
1222      bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
1223      qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
1224	     vma_compare);
1225      for (i = 0; i < hdr_info->fde_count; i++)
1226	{
1227	  bfd_put_32 (abfd,
1228		      hdr_info->array[i].initial_loc
1229		      - sec->output_section->vma,
1230		      contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
1231	  bfd_put_32 (abfd,
1232		      hdr_info->array[i].fde - sec->output_section->vma,
1233		      contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
1234	}
1235    }
1236
1237  return bfd_set_section_contents (abfd, sec->output_section,
1238				   contents, (file_ptr) sec->output_offset,
1239                                   sec->_cooked_size);
1240}
1241