// attributes.h -- object attributes for gold   -*- C++ -*-

// Copyright (C) 2009-2021 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)
