コード例 #1
0
ファイル: elf-s390-common.c プロジェクト: autc04/Retro68
/* Merge object attributes from IBFD into OBFD.  Raise an error if
   there are conflicting attributes.  */
static bfd_boolean
elf_s390_merge_obj_attributes (bfd *ibfd, struct bfd_link_info *info)
{
  bfd *obfd = info->output_bfd;
  obj_attribute *in_attr, *in_attrs;
  obj_attribute *out_attr, *out_attrs;

  if (!elf_known_obj_attributes_proc (obfd)[0].i)
    {
      /* This is the first object.  Copy the attributes.  */
      _bfd_elf_copy_obj_attributes (ibfd, obfd);

      /* Use the Tag_null value to indicate the attributes have been
	 initialized.  */
      elf_known_obj_attributes_proc (obfd)[0].i = 1;

      return TRUE;
    }

  in_attrs = elf_known_obj_attributes (ibfd)[OBJ_ATTR_GNU];
  out_attrs = elf_known_obj_attributes (obfd)[OBJ_ATTR_GNU];

  /* Check for conflicting Tag_GNU_S390_ABI_Vector attributes and
     merge non-conflicting ones.  */
  in_attr = &in_attrs[Tag_GNU_S390_ABI_Vector];
  out_attr = &out_attrs[Tag_GNU_S390_ABI_Vector];

  if (in_attr->i > 2)
    _bfd_error_handler
      /* xgettext:c-format */
      (_("warning: %pB uses unknown vector ABI %d"), ibfd,
       in_attr->i);
  else if (out_attr->i > 2)
    _bfd_error_handler
      /* xgettext:c-format */
      (_("warning: %pB uses unknown vector ABI %d"), obfd,
       out_attr->i);
  else if (in_attr->i != out_attr->i)
    {
      out_attr->type = ATTR_TYPE_FLAG_INT_VAL;

      if (in_attr->i && out_attr->i)
	{
	  const char abi_str[3][9] = { "none", "software", "hardware" };

	  _bfd_error_handler
	    /* xgettext:c-format */
	    (_("warning: %pB uses vector %s ABI, %pB uses %s ABI"),
	     ibfd, abi_str[in_attr->i], obfd, abi_str[out_attr->i]);
	}
      if (in_attr->i > out_attr->i)
	out_attr->i = in_attr->i;
    }

  /* Merge Tag_compatibility attributes and any common GNU ones.  */
  _bfd_elf_merge_object_attributes (ibfd, info);

  return TRUE;
}
コード例 #2
0
ファイル: elf-attrs.c プロジェクト: BackupGGCode/propgcc
/* Copy the object attributes from IBFD to OBFD.  */
void
_bfd_elf_copy_obj_attributes (bfd *ibfd, bfd *obfd)
{
  obj_attribute *in_attr;
  obj_attribute *out_attr;
  obj_attribute_list *list;
  int i;
  int vendor;

  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
    {
      in_attr
	= &elf_known_obj_attributes (ibfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE];
      out_attr
	= &elf_known_obj_attributes (obfd)[vendor][LEAST_KNOWN_OBJ_ATTRIBUTE];
      for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
	{
	  out_attr->type = in_attr->type;
	  out_attr->i = in_attr->i;
	  if (in_attr->s && *in_attr->s)
	    out_attr->s = _bfd_elf_attr_strdup (obfd, in_attr->s);
	  in_attr++;
	  out_attr++;
	}

      for (list = elf_other_obj_attributes (ibfd)[vendor];
	   list;
	   list = list->next)
	{
	  in_attr = &list->attr;
	  switch (in_attr->type & (ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL))
	    {
	    case ATTR_TYPE_FLAG_INT_VAL:
	      bfd_elf_add_obj_attr_int (obfd, vendor, list->tag, in_attr->i);
	      break;
	    case ATTR_TYPE_FLAG_STR_VAL:
	      bfd_elf_add_obj_attr_string (obfd, vendor, list->tag,
					   in_attr->s);
	      break;
	    case ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL:
	      bfd_elf_add_obj_attr_int_string (obfd, vendor, list->tag,
					       in_attr->i, in_attr->s);
	      break;
	    default:
	      abort ();
	    }
	}
    }
}
コード例 #3
0
ファイル: elf-attrs.c プロジェクト: BackupGGCode/propgcc
/* Return the size of the object attributes section for VENDOR
   (OBJ_ATTR_PROC or OBJ_ATTR_GNU), or 0 if there are no attributes
   for that vendor to record and the vendor is OBJ_ATTR_GNU.  */
static bfd_vma
vendor_obj_attr_size (bfd *abfd, int vendor)
{
  bfd_vma size;
  obj_attribute *attr;
  obj_attribute_list *list;
  int i;
  const char *vendor_name = vendor_obj_attr_name (abfd, vendor);

  if (!vendor_name)
    return 0;

  attr = elf_known_obj_attributes (abfd)[vendor];
  size = 0;
  for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
    size += obj_attr_size (i, &attr[i]);

  for (list = elf_other_obj_attributes (abfd)[vendor];
       list;
       list = list->next)
    size += obj_attr_size (list->tag, &list->attr);

  /* <size> <vendor_name> NUL 0x1 <size> */
  return ((size || vendor == OBJ_ATTR_PROC)
	  ? size + 10 + strlen (vendor_name)
	  : 0);
}
コード例 #4
0
ファイル: elf-attrs.c プロジェクト: BackupGGCode/propgcc
/* Write the contents of the object attributes section (length SIZE)
   for VENDOR to CONTENTS.  */
static void
vendor_set_obj_attr_contents (bfd *abfd, bfd_byte *contents, bfd_vma size,
			      int vendor)
{
  bfd_byte *p;
  obj_attribute *attr;
  obj_attribute_list *list;
  int i;
  const char *vendor_name = vendor_obj_attr_name (abfd, vendor);
  size_t vendor_length = strlen (vendor_name) + 1;

  p = contents;
  bfd_put_32 (abfd, size, p);
  p += 4;
  memcpy (p, vendor_name, vendor_length);
  p += vendor_length;
  *(p++) = Tag_File;
  bfd_put_32 (abfd, size - 4 - vendor_length, p);
  p += 4;

  attr = elf_known_obj_attributes (abfd)[vendor];
  for (i = LEAST_KNOWN_OBJ_ATTRIBUTE; i < NUM_KNOWN_OBJ_ATTRIBUTES; i++)
    {
      int tag = i;
      if (get_elf_backend_data (abfd)->obj_attrs_order)
	tag = get_elf_backend_data (abfd)->obj_attrs_order (i);
      p = write_obj_attribute (p, tag, &attr[tag]);
    }

  for (list = elf_other_obj_attributes (abfd)[vendor];
       list;
       list = list->next)
    p = write_obj_attribute (p, list->tag, &list->attr);
}
コード例 #5
0
ファイル: elf-attrs.c プロジェクト: BackupGGCode/propgcc
bfd_boolean
_bfd_elf_merge_object_attributes (bfd *ibfd, bfd *obfd)
{
  obj_attribute *in_attr;
  obj_attribute *out_attr;
  int vendor;

  /* The only common attribute is currently Tag_compatibility,
     accepted in both processor and "gnu" sections.  */
  for (vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; vendor++)
    {
      /* Handle Tag_compatibility.  The tags are only compatible if the flags
	 are identical and, if the flags are '1', the strings are identical.
	 If the flags are non-zero, then we can only use the string "gnu".  */
      in_attr = &elf_known_obj_attributes (ibfd)[vendor][Tag_compatibility];
      out_attr = &elf_known_obj_attributes (obfd)[vendor][Tag_compatibility];

      if (in_attr->i > 0 && strcmp (in_attr->s, "gnu") != 0)
	{
	  _bfd_error_handler
		(_("error: %B: Object has vendor-specific contents that "
		   "must be processed by the '%s' toolchain"),
		 ibfd, in_attr->s);
	  return FALSE;
	}

      if (in_attr->i != out_attr->i
	  || (in_attr->i != 0 && strcmp (in_attr->s, out_attr->s) != 0))
	{
	  _bfd_error_handler (_("error: %B: Object tag '%d, %s' is "
				"incompatible with tag '%d, %s'"),
			      ibfd,
			      in_attr->i, in_attr->s ? in_attr->s : "",
			      out_attr->i, out_attr->s ? out_attr->s : "");
	  return FALSE;
	}
    }

  return TRUE;
}
コード例 #6
0
ファイル: elf-attrs.c プロジェクト: BackupGGCode/propgcc
/* Return the value of an integer object attribute.  */
int
bfd_elf_get_obj_attr_int (bfd *abfd, int vendor, int tag)
{
  obj_attribute_list *p;

  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
    {
      /* Known tags are preallocated.  */
      return elf_known_obj_attributes (abfd)[vendor][tag].i;
    }
  else
    {
      for (p = elf_other_obj_attributes (abfd)[vendor];
	   p;
	   p = p->next)
	{
	  if (tag == p->tag)
	    return p->attr.i;
	  if (tag < p->tag)
	    break;
	}
      return 0;
    }
}
コード例 #7
0
ファイル: elf-attrs.c プロジェクト: BackupGGCode/propgcc
/* Allocate/find an object attribute.  */
static obj_attribute *
elf_new_obj_attr (bfd *abfd, int vendor, int tag)
{
  obj_attribute *attr;
  obj_attribute_list *list;
  obj_attribute_list *p;
  obj_attribute_list **lastp;


  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
    {
      /* Known tags are preallocated.  */
      attr = &elf_known_obj_attributes (abfd)[vendor][tag];
    }
  else
    {
      /* Create a new tag.  */
      list = (obj_attribute_list *)
	bfd_alloc (abfd, sizeof (obj_attribute_list));
      memset (list, 0, sizeof (obj_attribute_list));
      list->tag = tag;
      /* Keep the tag list in order.  */
      lastp = &elf_other_obj_attributes (abfd)[vendor];
      for (p = *lastp; p; p = p->next)
	{
	  if (tag < p->tag)
	    break;
	  lastp = &p->next;
	}
      list->next = *lastp;
      *lastp = list;
      attr = &list->attr;
    }

  return attr;
}