gas/
authorRichard Sandiford <rdsandiford@googlemail.com>
Tue, 20 May 2014 18:02:41 +0000 (19:02 +0100)
committerRichard Sandiford <rdsandiford@googlemail.com>
Tue, 20 May 2014 18:02:41 +0000 (19:02 +0100)
* config/obj-elf.h (obj_elf_seen_attribute): Declare.
* config/obj-elf.c (recorded_attribute_info): New structure.
(recorded_attributes): New variable.
(record_attribute, obj_elf_seen_attribute): New functions.
(obj_elf_vendor_attribute): Record which attributes have been seen.

gas/ChangeLog
gas/config/obj-elf.c
gas/config/obj-elf.h

index f873e2b..30b616e 100644 (file)
@@ -1,3 +1,11 @@
+2014-05-20  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * config/obj-elf.h (obj_elf_seen_attribute): Declare.
+       * config/obj-elf.c (recorded_attribute_info): New structure.
+       (recorded_attributes): New variable.
+       (record_attribute, obj_elf_seen_attribute): New functions.
+       (obj_elf_vendor_attribute): Record which attributes have been seen.
+
 2014-05-20  Nick Clifton  <nickc@redhat.com>
 
        * config/tc-msp430.c (CHECK_RELOC_MSP430): Add OP parameter.
index 52c6b64..e406f7b 100644 (file)
@@ -1458,6 +1458,62 @@ skip_past_char (char ** str, char c)
 }
 #define skip_past_comma(str) skip_past_char (str, ',')
 
+/* A list of attributes that have been explicitly set by the assembly code.
+   VENDOR is the vendor id, BASE is the tag shifted right by the number
+   of bits in MASK, and bit N of MASK is set if tag BASE+N has been set.  */
+struct recorded_attribute_info {
+  struct recorded_attribute_info *next;
+  int vendor;
+  unsigned int base;
+  unsigned long mask;
+};
+static struct recorded_attribute_info *recorded_attributes;
+
+/* Record that we have seen an explicit specification of attribute TAG
+   for vendor VENDOR.  */
+
+static void
+record_attribute (int vendor, unsigned int tag)
+{
+  unsigned int base;
+  unsigned long mask;
+  struct recorded_attribute_info *rai;
+
+  base = tag / (8 * sizeof (rai->mask));
+  mask = 1UL << (tag % (8 * sizeof (rai->mask)));
+  for (rai = recorded_attributes; rai; rai = rai->next)
+    if (rai->vendor == vendor && rai->base == base)
+      {
+       rai->mask |= mask;
+       return;
+      }
+
+  rai = XNEW (struct recorded_attribute_info);
+  rai->next = recorded_attributes;
+  rai->vendor = vendor;
+  rai->base = base;
+  rai->mask = mask;
+  recorded_attributes = rai;
+}
+
+/* Return true if we have seen an explicit specification of attribute TAG
+   for vendor VENDOR.  */
+
+bfd_boolean
+obj_elf_seen_attribute (int vendor, unsigned int tag)
+{
+  unsigned int base;
+  unsigned long mask;
+  struct recorded_attribute_info *rai;
+
+  base = tag / (8 * sizeof (rai->mask));
+  mask = 1UL << (tag % (8 * sizeof (rai->mask)));
+  for (rai = recorded_attributes; rai; rai = rai->next)
+    if (rai->vendor == vendor && rai->base == base)
+      return (rai->mask & mask) != 0;
+  return FALSE;
+}
+
 /* Parse an attribute directive for VENDOR.
    Returns the attribute number read, or zero on error.  */
 
@@ -1540,6 +1596,7 @@ obj_elf_vendor_attribute (int vendor)
       s = demand_copy_C_string (&len);
     }
 
+  record_attribute (vendor, tag);
   switch (type & 3)
     {
     case 3:
index 1e9d530..3f8f8f4 100644 (file)
@@ -165,6 +165,8 @@ extern void obj_elf_change_section
   (const char *, int, bfd_vma, int, const char *, int, int);
 extern struct fix *obj_elf_vtable_inherit (int);
 extern struct fix *obj_elf_vtable_entry (int);
+extern bfd_boolean obj_elf_seen_attribute
+  (int, unsigned int);
 extern int obj_elf_vendor_attribute (int);
 
 /* BFD wants to write the udata field, which is a no-no for the