1/* ELF attributes support (based on ARM EABI attributes).
2   Copyright 2005, 2006, 2007
3   Free Software Foundation, Inc.
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
20
21#include "sysdep.h"
22#include "bfd.h"
23#include "libiberty.h"
24#include "libbfd.h"
25#include "elf-bfd.h"
26
27/* Return the number of bytes needed by I in uleb128 format.  */
28static int
29uleb128_size (unsigned int i)
30{
31  int size;
32  size = 1;
33  while (i >= 0x80)
34    {
35      i >>= 7;
36      size++;
37    }
38  return size;
39}
40
41/* Return TRUE if the attribute has the default value (0/"").  */
42static bfd_boolean
43is_default_attr (obj_attribute *attr)
44{
45  if ((attr->type & 1) && attr->i != 0)
46    return FALSE;
47  if ((attr->type & 2) && attr->s && *attr->s)
48    return FALSE;
49
50  return TRUE;
51}
52
53/* Return the size of a single attribute.  */
54static bfd_vma
55obj_attr_size (int tag, obj_attribute *attr)
56{
57  bfd_vma size;
58
59  if (is_default_attr (attr))
60    return 0;
61
62  size = uleb128_size (tag);
63  if (attr->type & 1)
64    size += uleb128_size (attr->i);
65  if (attr->type & 2)
66    size += strlen ((char *)attr->s) + 1;
67  return size;
68}
69
70/* Return the vendor name for a given object attributes section.  */
71static const char *
72vendor_obj_attr_name (bfd *abfd, int vendor)
73{
74  return (vendor == OBJ_ATTR_PROC
75	  ? get_elf_backend_data (abfd)->obj_attrs_vendor
76	  : "gnu");
77}
78
79/* Return the size of the object attributes section for VENDOR
80   (OBJ_ATTR_PROC or OBJ_ATTR_GNU), or 0 if there are no attributes
81   for that vendor to record and the vendor is OBJ_ATTR_GNU.  */
82static bfd_vma
83vendor_obj_attr_size (bfd *abfd, int vendor)
84{
85  bfd_vma size;
86  obj_attribute *attr;
87  obj_attribute_list *list;
88  int i;
89  const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
90
91  if (!vendor_name)
92    return 0;
93
94  attr = elf_known_obj_attributes (abfd)[vendor];
95  size = 0;
96  for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
97    size += obj_attr_size (i, &attr[i]);
98
99  for (list = elf_other_obj_attributes (abfd)[vendor];
100       list;
101       list = list->next)
102    size += obj_attr_size (list->tag, &list->attr);
103
104  /* <size> <vendor_name> NUL 0x1 <size> */
105  return ((size || vendor == OBJ_ATTR_PROC)
106	  ? size + 10 + strlen (vendor_name)
107	  : 0);
108}
109
110/* Return the size of the object attributes section.  */
111bfd_vma
112bfd_elf_obj_attr_size (bfd *abfd)
113{
114  bfd_vma size;
115
116  size = vendor_obj_attr_size (abfd, OBJ_ATTR_PROC);
117  size += vendor_obj_attr_size (abfd, OBJ_ATTR_GNU);
118
119  /* 'A' <sections for each vendor> */
120  return (size ? size + 1 : 0);
121}
122
123/* Write VAL in uleb128 format to P, returning a pointer to the
124   following byte.  */
125static bfd_byte *
126write_uleb128 (bfd_byte *p, unsigned int val)
127{
128  bfd_byte c;
129  do
130    {
131      c = val & 0x7f;
132      val >>= 7;
133      if (val)
134	c |= 0x80;
135      *(p++) = c;
136    }
137  while (val);
138  return p;
139}
140
141/* Write attribute ATTR to butter P, and return a pointer to the following
142   byte.  */
143static bfd_byte *
144write_obj_attribute (bfd_byte *p, int tag, obj_attribute *attr)
145{
146  /* Suppress default entries.  */
147  if (is_default_attr (attr))
148    return p;
149
150  p = write_uleb128 (p, tag);
151  if (attr->type & 1)
152    p = write_uleb128 (p, attr->i);
153  if (attr->type & 2)
154    {
155      int len;
156
157      len = strlen (attr->s) + 1;
158      memcpy (p, attr->s, len);
159      p += len;
160    }
161
162  return p;
163}
164
165/* Write the contents of the object attributes section (length SIZE)
166   for VENDOR to CONTENTS.  */
167static void
168vendor_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size,
169			      int vendor)
170{
171  bfd_byte *p;
172  obj_attribute *attr;
173  obj_attribute_list *list;
174  int i;
175  const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
176  size_t vendor_length = strlen (vendor_name) + 1;
177
178  p = contents;
179  bfd_put_32 (abfd, size, p);
180  p += 4;
181  memcpy (p, vendor_name, vendor_length);
182  p += vendor_length;
183  *(p++) = Tag_File;
184  bfd_put_32 (abfd, size - 4 - vendor_length, p);
185  p += 4;
186
187  attr = elf_known_obj_attributes (abfd)[vendor];
188  for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
189    p = write_obj_attribute (p, i, &attr[i]);
190
191  for (list = elf_other_obj_attributes (abfd)[vendor];
192       list;
193       list = list->next)
194    p = write_obj_attribute (p, list->tag, &list->attr);
195}
196
197/* Write the contents of the object attributes section to CONTENTS.  */
198void
199bfd_elf_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size)
200{
201  bfd_byte *p;
202  int vendor;
203  bfd_vma my_size;
204
205  p = contents;
206  *(p++) = 'A';
207  my_size = 1;
208  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
209    {
210      bfd_vma vendor_size = vendor_obj_attr_size (abfd, vendor);
211      if (vendor_size)
212	vendor_set_obj_attr_contents (abfd, p, vendor_size, vendor);
213      p += vendor_size;
214      my_size += vendor_size;
215    }
216
217  if (size != my_size)
218    abort ();
219}
220
221/* Allocate/find an object attribute.  */
222static obj_attribute *
223elf_new_obj_attr (bfd *abfd, int vendor, int tag)
224{
225  obj_attribute *attr;
226  obj_attribute_list *list;
227  obj_attribute_list *p;
228  obj_attribute_list **lastp;
229
230
231  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
232    {
233      /* Knwon tags are preallocated.  */
234      attr = &elf_known_obj_attributes (abfd)[vendor][tag];
235    }
236  else
237    {
238      /* Create a new tag.  */
239      list = (obj_attribute_list *)
240	bfd_alloc (abfd, sizeof (obj_attribute_list));
241      memset (list, 0, sizeof (obj_attribute_list));
242      list->tag = tag;
243      /* Keep the tag list in order.  */
244      lastp = &elf_other_obj_attributes (abfd)[vendor];
245      for (p = *lastp; p; p = p->next)
246	{
247	  if (tag < p->tag)
248	    break;
249	  lastp = &p->next;
250	}
251      list->next = *lastp;
252      *lastp = list;
253      attr = &list->attr;
254    }
255
256  return attr;
257}
258
259/* Return the value of an integer object attribute.  */
260int
261bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, int tag)
262{
263  obj_attribute_list *p;
264
265  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
266    {
267      /* Knwon tags are preallocated.  */
268      return elf_known_obj_attributes (abfd)[vendor][tag].i;
269    }
270  else
271    {
272      for (p = elf_other_obj_attributes (abfd)[vendor];
273	   p;
274	   p = p->next)
275	{
276	  if (tag == p->tag)
277	    return p->attr.i;
278	  if (tag < p->tag)
279	    break;
280	}
281      return 0;
282    }
283}
284
285/* Add an integer object attribute.  */
286void
287bfd_elf_add_obj_attr_int (bfd *abfd, int vendor, int tag, unsigned int i)
288{
289  obj_attribute *attr;
290
291  attr = elf_new_obj_attr (abfd, vendor, tag);
292  attr->type = 1;
293  attr->i = i;
294}
295
296/* Duplicate an object attribute string value.  */
297char *
298_bfd_elf_attr_strdup (bfd *abfd, const char * s)
299{
300  char * p;
301  int len;
302
303  len = strlen (s) + 1;
304  p = (char *) bfd_alloc (abfd, len);
305  return memcpy (p, s, len);
306}
307
308/* Add a string object attribute.  */
309void
310bfd_elf_add_obj_attr_string (bfd *abfd, int vendor, int tag, const char *s)
311{
312  obj_attribute *attr;
313
314  attr = elf_new_obj_attr (abfd, vendor, tag);
315  attr->type = 2;
316  attr->s = _bfd_elf_attr_strdup (abfd, s);
317}
318
319/* Add a Tag_compatibility object attribute.  */
320void
321bfd_elf_add_obj_attr_compat (bfd *abfd, int vendor, unsigned int i,
322			     const char *s)
323{
324  obj_attribute_list *list;
325  obj_attribute_list *p;
326  obj_attribute_list **lastp;
327
328  list = (obj_attribute_list *)
329    bfd_alloc (abfd, sizeof (obj_attribute_list));
330  memset (list, 0, sizeof (obj_attribute_list));
331  list->tag = Tag_compatibility;
332  list->attr.type = 3;
333  list->attr.i = i;
334  list->attr.s = _bfd_elf_attr_strdup (abfd, s);
335
336  lastp = &elf_other_obj_attributes (abfd)[vendor];
337  for (p = *lastp; p; p = p->next)
338    {
339      int cmp;
340      if (p->tag != Tag_compatibility)
341	break;
342      cmp = strcmp(s, p->attr.s);
343      if (cmp < 0 || (cmp == 0 && i < p->attr.i))
344	break;
345      lastp = &p->next;
346    }
347  list->next = *lastp;
348  *lastp = list;
349}
350
351/* Copy the object attributes from IBFD to OBFD.  */
352void
353_bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd)
354{
355  obj_attribute *in_attr;
356  obj_attribute *out_attr;
357  obj_attribute_list *list;
358  int i;
359  int vendor;
360
361  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
362    {
363      in_attr = &elf_known_obj_attributes (ibfd)[vendor][4];
364      out_attr = &elf_known_obj_attributes (obfd)[vendor][4];
365      for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
366	{
367	  out_attr->type = in_attr->type;
368	  out_attr->i = in_attr->i;
369	  if (in_attr->s && *in_attr->s)
370	    out_attr->s = _bfd_elf_attr_strdup (obfd, in_attr->s);
371	  in_attr++;
372	  out_attr++;
373	}
374
375      for (list = elf_other_obj_attributes (ibfd)[vendor];
376	   list;
377	   list = list->next)
378	{
379	  in_attr = &list->attr;
380	  switch (in_attr->type)
381	    {
382	    case 1:
383	      bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i);
384	      break;
385	    case 2:
386	      bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
387					   in_attr->s);
388	      break;
389	    case 3:
390	      bfd_elf_add_obj_attr_compat (obfd, vendor, in_attr->i,
391					   in_attr->s);
392	      break;
393	    default:
394	      abort ();
395	    }
396	}
397    }
398}
399
400/* Determine whether a GNU object attribute tag takes an integer, a
401   string or both.  */
402static int
403gnu_obj_attrs_arg_type (int tag)
404{
405  /* Except for Tag_compatibility, for GNU attributes we follow the
406     same rule ARM ones > 32 follow: odd-numbered tags take strings
407     and even-numbered tags take integers.  In addition, tag & 2 is
408     nonzero for architecture-independent tags and zero for
409     architecture-dependent ones.  */
410  if (tag == Tag_compatibility)
411    return 3;
412  else
413    return (tag & 1) != 0 ? 2 : 1;
414}
415
416/* Determine what arguments an attribute tag takes.  */
417int
418_bfd_elf_obj_attrs_arg_type (bfd *abfd, int vendor, int tag)
419{
420  switch (vendor)
421    {
422    case OBJ_ATTR_PROC:
423      return get_elf_backend_data (abfd)->obj_attrs_arg_type (tag);
424      break;
425    case OBJ_ATTR_GNU:
426      return gnu_obj_attrs_arg_type (tag);
427      break;
428    default:
429      abort ();
430    }
431}
432
433/* Parse an object attributes section.  */
434void
435_bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
436{
437  bfd_byte *contents;
438  bfd_byte *p;
439  bfd_vma len;
440  const char *std_section;
441
442  contents = bfd_malloc (hdr->sh_size);
443  if (!contents)
444    return;
445  if (!bfd_get_section_contents (abfd, hdr->bfd_section, contents, 0,
446				 hdr->sh_size))
447    {
448      free (contents);
449      return;
450    }
451  p = contents;
452  std_section = get_elf_backend_data (abfd)->obj_attrs_vendor;
453  if (*(p++) == 'A')
454    {
455      len = hdr->sh_size - 1;
456      while (len > 0)
457	{
458	  int namelen;
459	  bfd_vma section_len;
460	  int vendor;
461
462	  section_len = bfd_get_32 (abfd, p);
463	  p += 4;
464	  if (section_len > len)
465	    section_len = len;
466	  len -= section_len;
467	  namelen = strlen ((char *)p) + 1;
468	  section_len -= namelen + 4;
469	  if (std_section && strcmp ((char *)p, std_section) == 0)
470	    vendor = OBJ_ATTR_PROC;
471	  else if (strcmp ((char *)p, "gnu") == 0)
472	    vendor = OBJ_ATTR_GNU;
473	  else
474	    {
475	      /* Other vendor section.  Ignore it.  */
476	      p += namelen + section_len;
477	      continue;
478	    }
479
480	  p += namelen;
481	  while (section_len > 0)
482	    {
483	      int tag;
484	      unsigned int n;
485	      unsigned int val;
486	      bfd_vma subsection_len;
487	      bfd_byte *end;
488
489	      tag = read_unsigned_leb128 (abfd, p, &n);
490	      p += n;
491	      subsection_len = bfd_get_32 (abfd, p);
492	      p += 4;
493	      if (subsection_len > section_len)
494		subsection_len = section_len;
495	      section_len -= subsection_len;
496	      subsection_len -= n + 4;
497	      end = p + subsection_len;
498	      switch (tag)
499		{
500		case Tag_File:
501		  while (p < end)
502		    {
503		      int type;
504
505		      tag = read_unsigned_leb128 (abfd, p, &n);
506		      p += n;
507		      type = _bfd_elf_obj_attrs_arg_type (abfd, vendor, tag);
508		      switch (type)
509			{
510			case 3:
511			  val = read_unsigned_leb128 (abfd, p, &n);
512			  p += n;
513			  bfd_elf_add_obj_attr_compat (abfd, vendor, val,
514						       (char *)p);
515			  p += strlen ((char *)p) + 1;
516			  break;
517			case 2:
518			  bfd_elf_add_obj_attr_string (abfd, vendor, tag,
519						       (char *)p);
520			  p += strlen ((char *)p) + 1;
521			  break;
522			case 1:
523			  val = read_unsigned_leb128 (abfd, p, &n);
524			  p += n;
525			  bfd_elf_add_obj_attr_int (abfd, vendor, tag, val);
526			  break;
527			default:
528			  abort ();
529			}
530		    }
531		  break;
532		case Tag_Section:
533		case Tag_Symbol:
534		  /* Don't have anywhere convenient to attach these.
535		     Fall through for now.  */
536		default:
537		  /* Ignore things we don't kow about.  */
538		  p += subsection_len;
539		  subsection_len = 0;
540		  break;
541		}
542	    }
543	}
544    }
545  free (contents);
546}
547
548/* Merge common object attributes from IBFD into OBFD.  Raise an error
549   if there are conflicting attributes.  Any processor-specific
550   attributes have already been merged.  This must be called from the
551   bfd_elfNN_bfd_merge_private_bfd_data hook for each individual
552   target, along with any target-specific merging.  Because there are
553   no common attributes other than Tag_compatibility at present, and
554   non-"gnu" Tag_compatibility is not expected in "gnu" sections, this
555   is not presently called for targets without their own
556   attributes.  */
557
558bfd_boolean
559_bfd_elf_merge_object_attributes (bfd *ibfd, bfd *obfd)
560{
561  obj_attribute *in_attr;
562  obj_attribute *out_attr;
563  obj_attribute_list *in_list;
564  obj_attribute_list *out_list;
565  int vendor;
566
567  /* The only common attribute is currently Tag_compatibility,
568     accepted in both processor and "gnu" sections.  */
569  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
570    {
571      in_list = elf_other_obj_attributes (ibfd)[vendor];
572      out_list = elf_other_obj_attributes (ibfd)[vendor];
573      while (in_list && in_list->tag == Tag_compatibility)
574	{
575	  in_attr = &in_list->attr;
576	  if (in_attr->i == 0)
577	    continue;
578	  if (in_attr->i == 1 && strcmp (in_attr->s, "gnu") != 0)
579	    {
580	      _bfd_error_handler
581		(_("ERROR: %B: Must be processed by '%s' toolchain"),
582		 ibfd, in_attr->s);
583	      return FALSE;
584	    }
585	  if (!out_list || out_list->tag != Tag_compatibility
586	      || strcmp (in_attr->s, out_list->attr.s) != 0)
587	    {
588	      /* Add this compatibility tag to the output.  */
589	      bfd_elf_add_proc_attr_compat (obfd, in_attr->i, in_attr->s);
590	      continue;
591	    }
592	  out_attr = &out_list->attr;
593	  /* Check all the input tags with the same identifier.  */
594	  for (;;)
595	    {
596	      if (out_list->tag != Tag_compatibility
597		  || in_attr->i != out_attr->i
598		  || strcmp (in_attr->s, out_attr->s) != 0)
599		{
600		  _bfd_error_handler
601		    (_("ERROR: %B: Incompatible object tag '%s':%d"),
602		     ibfd, in_attr->s, in_attr->i);
603		  return FALSE;
604		}
605	      in_list = in_list->next;
606	      if (in_list->tag != Tag_compatibility
607		  || strcmp (in_attr->s, in_list->attr.s) != 0)
608		break;
609	      in_attr = &in_list->attr;
610	      out_list = out_list->next;
611	      if (out_list)
612		out_attr = &out_list->attr;
613	    }
614
615	  /* Check the output doesn't have extra tags with this identifier.  */
616	  if (out_list && out_list->tag == Tag_compatibility
617	      && strcmp (in_attr->s, out_list->attr.s) == 0)
618	    {
619	      _bfd_error_handler
620		(_("ERROR: %B: Incompatible object tag '%s':%d"),
621		 ibfd, in_attr->s, out_list->attr.i);
622	      return FALSE;
623	    }
624	}
625    }
626
627  return TRUE;
628}
629