From: Richard Sandiford Date: Tue, 20 May 2014 18:02:41 +0000 (+0100) Subject: gas/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9440a9045928d3d4624b8dbcfbd98587a49d35e7;p=binutils-gdb.git gas/ * 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. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index f873e2b968e..30b616e0f71 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2014-05-20 Richard Sandiford + + * 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 * config/tc-msp430.c (CHECK_RELOC_MSP430): Add OP parameter. diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index 52c6b641227..e406f7b61e9 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -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: diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h index 1e9d5307eec..3f8f8f4947d 100644 --- a/gas/config/obj-elf.h +++ b/gas/config/obj-elf.h @@ -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