// attributes.cc -- object attributes for gold

// 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.

#include "gold.h"

#include <limits>

#include "attributes.h"
#include "elfcpp.h"
#include "target.h"
#include "parameters.h"
#include "int_encoding.h"

namespace gold
{

// Object_attribute methods.

// Return size of attribute encode in ULEB128.

size_t
Object_attribute::size(int tag) const
{
  // Attributes with default values are not written out.
  if (this->is_default_attribute())
    return 0;

  size_t size = get_length_as_unsigned_LEB_128(tag);
  if (Object_attribute::attribute_type_has_int_value(this->type_))
    size += get_length_as_unsigned_LEB_128(this->int_value_);
  if (Object_attribute::attribute_type_has_string_value(this->type_))
    size += this->string_value_.size() + 1;
  return size;
}

// Whether this has the default value (0/"").

bool
Object_attribute::is_default_attribute() const
{
  if (Object_attribute::attribute_type_has_int_value(this->type_)
      && this->int_value_ != 0)
    return false;
  if (Object_attribute::attribute_type_has_string_value(this->type_)
      && !this->string_value_.empty())
    return false;
  if (Object_attribute::attribute_type_has_no_default(this->type_))
    return false;

  return true;
}

// Whether this matches another Object_attribute OA in merging.
// Two Object_attributes match if they have the same values.

bool
Object_attribute::matches(const Object_attribute& oa) const
{
  return ((this->int_value_ != oa.int_value_)
	  && (this->string_value_ == oa.string_value_));
}

// Write this with TAG to a BUFFER.

void
Object_attribute::write(
    int tag,
    std::vector<unsigned char>* buffer) const
{
  // No need to write default attributes.
  if (this->is_default_attribute())
    return;
  
  // Write tag.
  write_unsigned_LEB_128(buffer, convert_types<uint64_t, int>(tag));

  // Write integer value.
  if (Object_attribute::attribute_type_has_int_value(this->type_))
    write_unsigned_LEB_128(buffer,
			   convert_types<uint64_t, int>(this->int_value_));

  // Write string value.
  if (Object_attribute::attribute_type_has_string_value(this->type_))
    {
      const unsigned char* start =
	reinterpret_cast<const unsigned char*>(this->string_value_.c_str());
      const unsigned char* end = start + this->string_value_.size() + 1;
      buffer->insert(buffer->end(), start, end); 
    }
}

// Vendor_object_attributes methods.

// Copying constructor.

Vendor_object_attributes::Vendor_object_attributes(
    const Vendor_object_attributes& voa)
{
  this->vendor_ = voa.vendor_;

  for (int i = 0; i < NUM_KNOWN_ATTRIBUTES; ++i)
    this->known_attributes_[i] = voa.known_attributes_[i];

  // We do not handle attribute deletion.  So this must be empty.
  gold_assert(this->other_attributes_.empty());

  for (Other_attributes::const_iterator p = voa.other_attributes_.begin();
       p != voa.other_attributes_.end();
       ++p)
    this->other_attributes_[p->first] = new Object_attribute(*(p->second));
}

// Size of this in number of bytes.

size_t
Vendor_object_attributes::size() const
{
  if (this->name() == NULL)
    return 0;

  size_t data_size = 0;
  for (int i = 4; i < NUM_KNOWN_ATTRIBUTES; ++i)
    data_size += this->known_attributes_[i].size(i);

  for (Other_attributes::const_iterator p = this->other_attributes_.begin();
       p != this->other_attributes_.end();
       ++p)
    data_size += p->second->size(p->first);

  // <size> <vendor_name> NUL 0x1 <size>
  return ((data_size != 0
	   || this->vendor_ == Object_attribute::OBJ_ATTR_PROC)
	  ? data_size + strlen(this->name()) + 2 + 2 * 4
	  : 0);
}

// Return a new attribute associated with TAG.

Object_attribute*
Vendor_object_attributes::new_attribute(int tag)
{
  int type = Object_attribute::arg_type(this->vendor_, tag);

  if (tag < NUM_KNOWN_ATTRIBUTES)
    {
      this->known_attributes_[tag].set_type(type);
      return &this->known_attributes_[tag];
    }
  else
    {
      Object_attribute* attr = new Object_attribute();

      // This should be the first time we insert this.
      std::pair<Other_attributes::iterator, bool> ins =
	this->other_attributes_.insert(std::make_pair(tag, attr));
      gold_assert(ins.second);

      attr->set_type(type);
      return attr;
    }
}

// Return an attribute associated with TAG.

Object_attribute*
Vendor_object_attributes::get_attribute(int tag)
{
  if (tag < NUM_KNOWN_ATTRIBUTES)
    return &this->known_attributes_[tag];
  else
    {
      Other_attributes::iterator p =
	this->other_attributes_.find(tag);
      return p != this->other_attributes_.end() ? p->second : NULL;
    }
}

const Object_attribute*
Vendor_object_attributes::get_attribute(int tag) const
{
  if (tag < NUM_KNOWN_ATTRIBUTES)
    return &this->known_attributes_[tag];
  else
    {
      Other_attributes::const_iterator p =
	this->other_attributes_.find(tag);
      return p != this->other_attributes_.end() ? p->second : NULL;
    }
}

// Write attributes to BUFFER.

void
Vendor_object_attributes::write(std::vector<unsigned char>* buffer) const
{
  // Write subsection size.
  size_t voa_size = this->size();
  uint32_t voa_size_as_u32 = convert_types<uint32_t, size_t>(voa_size);
  insert_into_vector<32>(buffer, voa_size_as_u32);

  // Write vendor name.
  const unsigned char* vendor_start =
    reinterpret_cast<const unsigned char*>(this->name());
  size_t vendor_length = strlen(this->name()) + 1;
  const unsigned char* vendor_end = vendor_start + vendor_length;
  buffer->insert(buffer->end(), vendor_start, vendor_end);

  // Write file tag.
  buffer->push_back(Object_attribute::Tag_File);

  // Write attributes size.
  uint32_t attributes_size_as_u32 =
    convert_types<uint32_t, size_t>(voa_size - 4 - vendor_length);
  insert_into_vector<32>(buffer, attributes_size_as_u32);

  // Write known attributes, skipping any defaults.
  for (int i = 4; i < NUM_KNOWN_ATTRIBUTES; ++i)
    {
      // A target may write known attributes in a special order. 
      // Call target hook to remap tags.  Attributes_order is the identity
      // function if no re-ordering is required.
      int tag = parameters->target().attributes_order(i);
      this->known_attributes_[tag].write(tag, buffer);
    }

  // Write other attributes.
  for (Other_attributes::const_iterator q = this->other_attributes_.begin();
       q != this->other_attributes_.end();
       ++q)
    q->second->write(q->first, buffer);
}

// Attributes_section_data methods.

// Compute encoded size of this.

size_t
Attributes_section_data::size() const
{
  size_t data_size = 0;
  for(int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
    data_size += this->vendor_object_attributes_[vendor]->size();

  // 'A' <sections for each vendor>
  return data_size != 0 ? data_size + 1 : 0;
}

// Construct an Attributes_section_data object by parsing section contents
// specified by VIEW and SIZE.

Attributes_section_data::Attributes_section_data(
    const unsigned char* view,
    section_size_type size)
{
  for (int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
    this->vendor_object_attributes_[vendor] =
      new Vendor_object_attributes(vendor);

  const unsigned char* p = view;
  p = view;
  if (size > 0 && p != NULL && *(p++) == 'A')
    {
      size--;
      while (size > 0)
	{
	  // Size of vendor attributes section.
	  section_size_type section_size =
	    convert_to_section_size_type(read_from_pointer<32>(&p));

	  if (section_size > size)
	    section_size = size;
	  size -= section_size;

	  const char* section_name = reinterpret_cast<const char*>(p);
	  section_size_type section_name_size = strlen(section_name) + 1;
	  section_size -= section_name_size + 4;

	  int vendor;
	  const char* std_section = parameters->target().attributes_vendor();
	  if (std_section != NULL && strcmp(section_name, std_section) == 0)
	    vendor = Object_attribute::OBJ_ATTR_PROC;
	  else if (strcmp(section_name, "gnu") == 0)
	    vendor = Object_attribute::OBJ_ATTR_GNU;
	  else
	    {
	      // Other vendor section.  Ignore it.
	      p += section_name_size + section_size;
	      continue;
	    }
	  p += section_name_size;

	  while (section_size > 0)
	    {
	      const unsigned char* subsection_start = p;

	      // Read vendor subsection index and size.
	      size_t uleb128_len;
	      uint64_t val = read_unsigned_LEB_128(p, &uleb128_len);
	      p += uleb128_len;

	      int tag = convert_types<int, uint64_t>(val);
	      section_size_type subsection_size =
		convert_to_section_size_type(read_from_pointer<32>(&p));
	      section_size -= subsection_size;
	      subsection_size -= (p - subsection_start);

	      const unsigned char* end = p + subsection_size;
	      switch (tag)
		{
		case Object_attribute::Tag_File:
		  while (p < end)
		    {
		      val = read_unsigned_LEB_128(p, &uleb128_len);
		      p += uleb128_len;
		      tag = convert_types<int, uint64_t>(val);
		      Vendor_object_attributes* pvoa =
			this->vendor_object_attributes_[vendor];
		      Object_attribute* attr = pvoa->new_attribute(tag);
		      const char* string_arg;
		      unsigned int int_arg;

		      int type = Object_attribute::arg_type(vendor, tag);
		      switch (type
			      & (Object_attribute::ATTR_TYPE_FLAG_INT_VAL
				 | Object_attribute::ATTR_TYPE_FLAG_STR_VAL))
			{
			case (Object_attribute::ATTR_TYPE_FLAG_INT_VAL
			      | Object_attribute::ATTR_TYPE_FLAG_STR_VAL):
			  val = read_unsigned_LEB_128(p, &uleb128_len);
			  p += uleb128_len;
			  int_arg = convert_types<unsigned int, uint64_t>(val);
			  string_arg = reinterpret_cast<const char *>(p);
			  attr->set_int_value(int_arg);
			  p += strlen(string_arg) + 1;
			  break;
			case Object_attribute::ATTR_TYPE_FLAG_STR_VAL:
			  string_arg = reinterpret_cast<const char *>(p);
			  attr->set_string_value(string_arg);
			  p += strlen(string_arg) + 1;
			  break;
			case Object_attribute::ATTR_TYPE_FLAG_INT_VAL:
			  val = read_unsigned_LEB_128(p, &uleb128_len);
			  p += uleb128_len;
			  int_arg = convert_types<unsigned int, uint64_t>(val);
			  attr->set_int_value(int_arg);
			  break;
			default:
			  gold_unreachable();
			}
		    }
		  break;
		case Object_attribute::Tag_Section:
		case Object_attribute::Tag_Symbol:
		  // Don't have anywhere convenient to attach these.
		  // Fall through for now.
		default:
		  // Ignore things we don't know about.
		  p += subsection_size;
		  subsection_size = 0;
		  break;
		}
	    }
	}
    }
}

// Merge target-independent attributes from another Attribute_section_data
// ASD from an object called NAME into this.

void
Attributes_section_data::merge(
    const char* name,
    const Attributes_section_data* pasd)
{
  // The only common attribute is currently Tag_compatibility,
  // accepted in both processor and "gnu" sections.
  for (int 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".
      const Object_attribute* in_attr =
	&pasd->known_attributes(vendor)[Object_attribute::Tag_compatibility];
      Object_attribute* out_attr =
	&this->known_attributes(vendor)[Object_attribute::Tag_compatibility];

      if (in_attr->int_value() > 0
	  && in_attr->string_value() != "gnu")
	{
	  gold_error(_("%s: must be processed by '%s' toolchain"),
		     name, in_attr->string_value().c_str());
	  return;
	}

      if (in_attr->int_value() != out_attr->int_value()
	  || in_attr->string_value() != out_attr->string_value())
	{
	  gold_error(_("%s: object tag '%d, %s' is "
		       "incompatible with tag '%d, %s'"),
		     name, in_attr->int_value(),
		     in_attr->string_value().c_str(),
		     out_attr->int_value(),
		     out_attr->string_value().c_str());
	}
    }
}

// Write to a buffer.

void
Attributes_section_data::write(std::vector<unsigned char>* buffer) const
{
  buffer->push_back('A');
  for (int vendor = OBJ_ATTR_FIRST; vendor <= OBJ_ATTR_LAST; ++vendor)
    if (this->vendor_object_attributes_[vendor]->size() != 0)
      this->vendor_object_attributes_[vendor]->write(buffer);
}

// Methods for Output_attributes_section_data.

// Write attributes section data to file OF.

void
Output_attributes_section_data::do_write(Output_file* of)
{
  off_t offset = this->offset();
  const section_size_type oview_size =
    convert_to_section_size_type(this->data_size());
  unsigned char* const oview = of->get_output_view(offset, oview_size);

  std::vector<unsigned char> buffer;
  this->attributes_section_data_.write(&buffer);
  gold_assert(convert_to_section_size_type(buffer.size()) == oview_size);
  memcpy(oview, &buffer.front(), buffer.size());
  of->write_output_view(this->offset(), oview_size, oview);
}

} // End namespace gold.
