123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412 |
- // attributes.h -- object attributes for gold -*- C++ -*-
- // Copyright (C) 2009-2015 Free Software Foundation, Inc.
- // Written by Doug Kwan <dougkwan@google.com>.
- // This file contains code adapted from BFD.
- // This file is part of gold.
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation; either version 3 of the License, or
- // (at your option) any later version.
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- // You should have received a copy of the GNU General Public License
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
- // MA 02110-1301, USA.
- // Handle object attributes.
- #ifndef GOLD_ATTRIBUTES_H
- #define GOLD_ATTRIBUTES_H
- #include <map>
- #include "parameters.h"
- #include "target.h"
- #include "output.h"
- #include "reduced_debug_output.h"
- namespace gold
- {
- // Object attribute values. The attribute tag is not stored in this object.
- class Object_attribute
- {
- public:
- // The value of an object attribute. The type indicates whether the
- // attribute holds and integer, a string, or both. It can also indicate that
- // there can be no default (i.e. all values must be written to file, even
- // zero).
- enum
- {
- ATTR_TYPE_FLAG_INT_VAL = (1 << 0),
- ATTR_TYPE_FLAG_STR_VAL = (1 << 1),
- ATTR_TYPE_FLAG_NO_DEFAULT = (1 << 2)
- };
- // Object attributes may either be defined by the processor ABI, index
- // OBJ_ATTR_PROC in the *_obj_attributes arrays, or be GNU-specific
- // (and possibly also processor-specific), index OBJ_ATTR_GNU.
- enum
- {
- OBJ_ATTR_PROC,
- OBJ_ATTR_GNU,
- OBJ_ATTR_FIRST = OBJ_ATTR_PROC,
- OBJ_ATTR_LAST = OBJ_ATTR_GNU
- };
- // The following object attribute tags are taken as generic, for all
- // targets and for "gnu" where there is no target standard.
- enum
- {
- Tag_NULL = 0,
- Tag_File = 1,
- Tag_Section = 2,
- Tag_Symbol = 3,
- Tag_compatibility = 32
- };
- Object_attribute()
- : type_(0), int_value_(0), string_value_()
- { }
- // Copying constructor. We need to implement this to copy the string value.
- Object_attribute(const Object_attribute& oa)
- : type_(oa.type_), int_value_(oa.int_value_), string_value_(oa.string_value_)
- { }
- ~Object_attribute()
- { }
- // Assignment operator. We need to implement this to copy the string value.
- Object_attribute&
- operator=(const Object_attribute& source)
- {
- this->type_ = source.type_;
- this->int_value_ = source.int_value_;
- this->string_value_ = source.string_value_;
- return *this;
- }
- // Return attribute type.
- int
- type() const
- { return this->type_; }
- // Set attribute type.
- void
- set_type(int type)
- { this->type_ = type; }
- // Return integer value.
- unsigned int
- int_value() const
- { return this->int_value_; }
- // Set integer value.
- void
- set_int_value(unsigned int i)
- { this->int_value_ = i; }
- // Return string value.
- const std::string&
- string_value() const
- { return this->string_value_; }
- // Set string value.
- void
- set_string_value(const std::string& s)
- { this->string_value_ = s; }
- void
- set_string_value(const char* s)
- { this->string_value_ = s; }
- // Whether attribute type has integer value.
- static bool
- attribute_type_has_int_value(int type)
- { return (type & ATTR_TYPE_FLAG_INT_VAL) != 0; }
- // Whether attribute type has string value.
- static bool
- attribute_type_has_string_value(int type)
- { return (type & ATTR_TYPE_FLAG_STR_VAL) != 0; }
- // Whether attribute type has no default value.
- static bool
- attribute_type_has_no_default(int type)
- { return (type & ATTR_TYPE_FLAG_NO_DEFAULT) != 0; }
- // Whether this has default value (0/"").
- bool
- is_default_attribute() const;
- // Return ULEB128 encoded size of tag and attribute.
- size_t
- size(int tag) const;
- // Whether this matches another object attribute in merging.
- bool
- matches(const Object_attribute& oa) const;
-
- // Write to attribute with tag to BUFFER.
- void
- write(int tag, std::vector<unsigned char>* buffer) const;
- // Determine what arguments an attribute tag takes.
- static int
- arg_type(int vendor, int tag)
- {
- switch (vendor)
- {
- case OBJ_ATTR_PROC:
- return parameters->target().attribute_arg_type(tag);
- case OBJ_ATTR_GNU:
- return Object_attribute::gnu_arg_type(tag);
- default:
- gold_unreachable();
- }
- }
- private:
- // Determine whether a GNU object attribute tag takes an integer, a
- // string or both. */
- static int
- gnu_arg_type(int tag)
- {
- // Except for Tag_compatibility, for GNU attributes we follow the
- // same rule ARM ones > 32 follow: odd-numbered tags take strings
- // and even-numbered tags take integers. In addition, tag & 2 is
- // nonzero for architecture-independent tags and zero for
- // architecture-dependent ones.
- if (tag == Object_attribute::Tag_compatibility)
- return ATTR_TYPE_FLAG_INT_VAL | ATTR_TYPE_FLAG_STR_VAL;
- else
- return (tag & 1) != 0 ? ATTR_TYPE_FLAG_STR_VAL : ATTR_TYPE_FLAG_INT_VAL;
- }
- // Attribute type.
- int type_;
- // Integer value.
- int int_value_;
- // String value.
- std::string string_value_;
- };
- // This class contains attributes of a particular vendor.
- class Vendor_object_attributes
- {
- public:
- // The maximum number of known object attributes for any target.
- static const int NUM_KNOWN_ATTRIBUTES = 71;
- Vendor_object_attributes(int vendor)
- : vendor_(vendor), other_attributes_()
- { }
- // Copying constructor.
- Vendor_object_attributes(const Vendor_object_attributes&);
- ~Vendor_object_attributes()
- {
- for (Other_attributes::iterator p = this->other_attributes_.begin();
- p != this->other_attributes_.end();
- ++p)
- delete p->second;
- }
- // Size of this in number of bytes.
- size_t
- size() const;
-
- // Name of this written vendor subsection.
- const char*
- name() const
- {
- return (this->vendor_ == Object_attribute::OBJ_ATTR_PROC
- ? parameters->target().attributes_vendor()
- : "gnu");
- }
- // Return an array of known attributes.
- Object_attribute*
- known_attributes()
- { return &this->known_attributes_[0]; }
- const Object_attribute*
- known_attributes() const
- { return &this->known_attributes_[0]; }
- typedef std::map<int, Object_attribute*> Other_attributes;
- // Return attributes other than the known ones.
- Other_attributes*
- other_attributes()
- { return &this->other_attributes_; }
- const Other_attributes*
- other_attributes() const
- { return &this->other_attributes_; }
- // Return a new attribute associated with TAG.
- Object_attribute*
- new_attribute(int tag);
- // Get an attribute
- Object_attribute*
- get_attribute(int tag);
- const Object_attribute*
- get_attribute(int tag) const;
- // Write to BUFFER.
- void
- write(std::vector<unsigned char>* buffer) const;
- private:
- // Vendor of the object attributes.
- int vendor_;
- // Attributes with known tags. There are store in an array for fast
- // access.
- Object_attribute known_attributes_[NUM_KNOWN_ATTRIBUTES];
- // Attributes with known tags. There are stored in a sorted container.
- Other_attributes other_attributes_;
- };
- // This class contains contents of an attributes section.
- class Attributes_section_data
- {
- public:
- // Construct an Attributes_section_data object by parsing section contents
- // in VIEW of SIZE.
- Attributes_section_data(const unsigned char* view, section_size_type size);
- // Copying constructor.
- Attributes_section_data(const Attributes_section_data& asd)
- {
- for (int vendor = Object_attribute::OBJ_ATTR_FIRST;
- vendor <= Object_attribute::OBJ_ATTR_LAST;
- ++vendor)
- this->vendor_object_attributes_[vendor] =
- new Vendor_object_attributes(*asd.vendor_object_attributes_[vendor]);
- }
-
- ~Attributes_section_data()
- {
- for (int vendor = Object_attribute::OBJ_ATTR_FIRST;
- vendor <= Object_attribute::OBJ_ATTR_LAST;
- ++vendor)
- delete this->vendor_object_attributes_[vendor];
- }
-
- // Return the size of this as number of bytes.
- size_t
- size() const;
- // Return an array of known attributes.
- Object_attribute*
- known_attributes(int vendor)
- {
- gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
- return this->vendor_object_attributes_[vendor]->known_attributes();
- }
- const Object_attribute*
- known_attributes(int vendor) const
- {
- gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
- return this->vendor_object_attributes_[vendor]->known_attributes();
- }
- // Return the other attributes.
- Vendor_object_attributes::Other_attributes*
- other_attributes(int vendor)
- {
- gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
- return this->vendor_object_attributes_[vendor]->other_attributes();
- }
- // Return the other attributes.
- const Vendor_object_attributes::Other_attributes*
- other_attributes(int vendor) const
- {
- gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
- return this->vendor_object_attributes_[vendor]->other_attributes();
- }
- // Return an attribute.
- Object_attribute*
- get_attribute(int vendor, int tag)
- {
- gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
- return this->vendor_object_attributes_[vendor]->get_attribute(tag);
- }
-
- const Object_attribute*
- get_attribute(int vendor, int tag) const
- {
- gold_assert(vendor >= OBJ_ATTR_FIRST && vendor <= OBJ_ATTR_LAST);
- return this->vendor_object_attributes_[vendor]->get_attribute(tag);
- }
-
- // Merge target-independent attributes from another Attributes_section_data
- // of an object called NAME.
- void
- merge(const char* name, const Attributes_section_data* pasd);
- // Write to byte stream in an unsigned char vector.
- void
- write(std::vector<unsigned char>*) const;
- private:
- // For convenience.
- static const int OBJ_ATTR_FIRST = Object_attribute::OBJ_ATTR_FIRST;
- static const int OBJ_ATTR_LAST = Object_attribute::OBJ_ATTR_LAST;
- // Vendor object attributes.
- Vendor_object_attributes* vendor_object_attributes_[OBJ_ATTR_LAST+1];
- };
- // This class is used for writing out an Attribute_section_data.
- class Output_attributes_section_data : public Output_section_data
- {
- public:
- Output_attributes_section_data(const Attributes_section_data& asd)
- : Output_section_data(1), attributes_section_data_(asd)
- { }
- protected:
- // Write to a map file.
- void
- do_print_to_mapfile(Mapfile* mapfile) const
- { mapfile->print_output_data(this, _("** attributes")); }
- // Write the data to the output file.
- void
- do_write(Output_file*);
-
- // Set final data size.
- void
- set_final_data_size()
- { this->set_data_size(attributes_section_data_.size()); }
- private:
- // Attributes_section_data corresponding to this.
- const Attributes_section_data& attributes_section_data_;
- };
- } // End namespace gold.
- #endif // !defined(GOLD_ATTRIBUTES_H)
|