155714Skris/* ELF attributes support (based on ARM EABI attributes).
255714Skris   Copyright 2005, 2006, 2007
355714Skris   Free Software Foundation, Inc.
455714Skris
555714Skris   This file is part of BFD, the Binary File Descriptor library.
655714Skris
755714Skris   This program is free software; you can redistribute it and/or modify
8280304Sjkim   it under the terms of the GNU General Public License as published by
955714Skris   the Free Software Foundation; either version 2 of the License, or
1055714Skris   (at your option) any later version.
1155714Skris
1255714Skris   This program is distributed in the hope that it will be useful,
1355714Skris   but WITHOUT ANY WARRANTY; without even the implied warranty of
1455714Skris   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15280304Sjkim   GNU General Public License for more details.
1655714Skris
1755714Skris   You should have received a copy of the GNU General Public License
1855714Skris   along with this program; if not, write to the Free Software
1955714Skris   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2055714Skris
2155714Skris#include "sysdep.h"
22280304Sjkim#include "bfd.h"
2355714Skris#include "libiberty.h"
2455714Skris#include "libbfd.h"
2555714Skris#include "elf-bfd.h"
2655714Skris
2755714Skris/* Return the number of bytes needed by I in uleb128 format.  */
2855714Skrisstatic int
2955714Skrisuleb128_size (unsigned int i)
3055714Skris{
3155714Skris  int size;
3255714Skris  size = 1;
3355714Skris  while (i >= 0x80)
3455714Skris    {
3555714Skris      i >>= 7;
3655714Skris      size++;
37280304Sjkim    }
3855714Skris  return size;
3955714Skris}
40280304Sjkim
4155714Skris/* Return TRUE if the attribute has the default value (0/"").  */
4255714Skrisstatic bfd_boolean
4355714Skrisis_default_attr (obj_attribute *attr)
4455714Skris{
4555714Skris  if ((attr->type & 1) && attr->i != 0)
4655714Skris    return FALSE;
4755714Skris  if ((attr->type & 2) && attr->s && *attr->s)
4855714Skris    return FALSE;
4955714Skris
5055714Skris  return TRUE;
5155714Skris}
52280304Sjkim
5355714Skris/* Return the size of a single attribute.  */
5455714Skrisstatic bfd_vma
5555714Skrisobj_attr_size (int tag, obj_attribute *attr)
5655714Skris{
5755714Skris  bfd_vma size;
5855714Skris
59238405Sjkim  if (is_default_attr (attr))
6055714Skris    return 0;
6155714Skris
6255714Skris  size = uleb128_size (tag);
6355714Skris  if (attr->type & 1)
6455714Skris    size += uleb128_size (attr->i);
65280304Sjkim  if (attr->type & 2)
66280304Sjkim    size += strlen ((char *)attr->s) + 1;
67280304Sjkim  return size;
68280304Sjkim}
69280304Sjkim
7055714Skris/* Return the vendor name for a given object attributes section.  */
7155714Skrisstatic const char *
7255714Skrisvendor_obj_attr_name (bfd *abfd, int vendor)
7355714Skris{
7455714Skris  return (vendor == OBJ_ATTR_PROC
75238405Sjkim	  ? get_elf_backend_data (abfd)->obj_attrs_vendor
76238405Sjkim	  : "gnu");
77280304Sjkim}
78280304Sjkim
79280304Sjkim/* Return the size of the object attributes section for VENDOR
80280304Sjkim   (OBJ_ATTR_PROC or OBJ_ATTR_GNU), or 0 if there are no attributes
81280304Sjkim   for that vendor to record and the vendor is OBJ_ATTR_GNU.  */
82238405Sjkimstatic bfd_vma
83238405Sjkimvendor_obj_attr_size (bfd *abfd, int vendor)
84280304Sjkim{
85280304Sjkim  bfd_vma size;
86280304Sjkim  obj_attribute *attr;
87280304Sjkim  obj_attribute_list *list;
88280304Sjkim  int i;
89280304Sjkim  const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
90280304Sjkim
9155714Skris  if (!vendor_name)
92280304Sjkim    return 0;
93280304Sjkim
94280304Sjkim  attr = elf_known_obj_attributes (abfd)[vendor];
95280304Sjkim  size = 0;
96280304Sjkim  for (i = 4; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
97280304Sjkim    size += obj_attr_size (i, &attr[i]);
98280304Sjkim
99280304Sjkim  for (list = elf_other_obj_attributes (abfd)[vendor];
100280304Sjkim       list;
101280304Sjkim       list = list->next)
10255714Skris    size += obj_attr_size (list->tag, &list->attr);
103280304Sjkim
104280304Sjkim  /* <size> <vendor_name> NUL 0x1 <size> */
105280304Sjkim  return ((size || vendor == OBJ_ATTR_PROC)
106280304Sjkim	  ? size + 10 + strlen (vendor_name)
107280304Sjkim	  : 0);
108280304Sjkim}
10955714Skris
110280304Sjkim/* Return the size of the object attributes section.  */
111280304Sjkimbfd_vma
112280304Sjkimbfd_elf_obj_attr_size (bfd *abfd)
113280304Sjkim{
114280304Sjkim  bfd_vma size;
115280304Sjkim
116280304Sjkim  size = vendor_obj_attr_size (abfd, OBJ_ATTR_PROC);
117280304Sjkim  size += vendor_obj_attr_size (abfd, OBJ_ATTR_GNU);
118280304Sjkim
11955714Skris  /* 'A' <sections for each vendor> */
120280304Sjkim  return (size ? size + 1 : 0);
121280304Sjkim}
122280304Sjkim
123280304Sjkim/* Write VAL in uleb128 format to P, returning a pointer to the
12455714Skris   following byte.  */
125280304Sjkimstatic bfd_byte *
126280304Sjkimwrite_uleb128 (bfd_byte *p, unsigned int val)
127280304Sjkim{
128280304Sjkim  bfd_byte c;
129280304Sjkim  do
130280304Sjkim    {
131280304Sjkim      c = val & 0x7f;
132280304Sjkim      val >>= 7;
13355714Skris      if (val)
134280304Sjkim	c |= 0x80;
135280304Sjkim      *(p++) = c;
136280304Sjkim    }
137280304Sjkim  while (val);
13855714Skris  return p;
139280304Sjkim}
140280304Sjkim
141280304Sjkim/* Write attribute ATTR to butter P, and return a pointer to the following
142280304Sjkim   byte.  */
143280304Sjkimstatic bfd_byte *
144280304Sjkimwrite_obj_attribute (bfd_byte *p, int tag, obj_attribute *attr)
145280304Sjkim{
146280304Sjkim  /* Suppress default entries.  */
14755714Skris  if (is_default_attr (attr))
148280304Sjkim    return p;
149280304Sjkim
150280304Sjkim  p = write_uleb128 (p, tag);
151280304Sjkim  if (attr->type & 1)
15255714Skris    p = write_uleb128 (p, attr->i);
153280304Sjkim  if (attr->type & 2)
154280304Sjkim    {
155280304Sjkim      int len;
156280304Sjkim
157280304Sjkim      len = strlen (attr->s) + 1;
158280304Sjkim      memcpy (p, attr->s, len);
159280304Sjkim      p += len;
160280304Sjkim    }
16155714Skris
162280304Sjkim  return p;
163280304Sjkim}
164280304Sjkim
165280304Sjkim/* Write the contents of the object attributes section (length SIZE)
166280304Sjkim   for VENDOR to CONTENTS.  */
167280304Sjkimstatic void
168280304Sjkimvendor_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size,
169280304Sjkim			      int vendor)
17055714Skris{
171280304Sjkim  bfd_byte *p;
172280304Sjkim  obj_attribute *attr;
173280304Sjkim  obj_attribute_list *list;
174280304Sjkim  int i;
175280304Sjkim  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