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