// freebsd.h -- FreeBSD support for gold    -*- C++ -*-

// Copyright 2009 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.

// 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 "target.h"
#include "target-select.h"

#ifndef GOLD_FREEBSD_H
#define GOLD_FREEBSD_H

namespace gold
{

// FreeBSD 4.1 and later wants the EI_OSABI field in the ELF header to
// be set to ELFOSABI_FREEBSD.  This is a subclass of Sized_target
// which supports that.  The real target would be a subclass of this
// one.  We permit combining FreeBSD and non-FreeBSD object files.
// The effect of this target is to set the code in the output file.

template<int size, bool big_endian>
class Target_freebsd : public Sized_target<size, big_endian>
{
 public:
  // Set the value to use for the EI_OSABI field in the ELF header.
  void
  set_osabi(elfcpp::ELFOSABI osabi)
  { this->osabi_ = osabi; }

 protected:
  Target_freebsd(const Target::Target_info* pti)
    : Sized_target<size, big_endian>(pti),
      osabi_(elfcpp::ELFOSABI_NONE)
  { }

  virtual void
  do_adjust_elf_header(unsigned char* view, int len) const;

 private:
  // Value to store in the EI_OSABI field of the ELF file header.
  elfcpp::ELFOSABI osabi_;
};

// Adjust the ELF file header by storing the requested value in the
// OSABI field.  This is for FreeBSD support.

template<int size, bool big_endian>
inline void
Target_freebsd<size, big_endian>::do_adjust_elf_header(unsigned char* view,
						       int len) const
{
  if (this->osabi_ != elfcpp::ELFOSABI_NONE)
    {
      gold_assert(len == elfcpp::Elf_sizes<32>::ehdr_size);

      elfcpp::Ehdr<32, false> ehdr(view);
      unsigned char e_ident[elfcpp::EI_NIDENT];
      memcpy(e_ident, ehdr.get_e_ident(), elfcpp::EI_NIDENT);

      e_ident[elfcpp::EI_OSABI] = this->osabi_;

      elfcpp::Ehdr_write<32, false> oehdr(view);
      oehdr.put_e_ident(e_ident);
    }
}

// A target selector for targets which permit combining both FreeBSD
// and non-FreeBSD object files.

class Target_selector_freebsd : public Target_selector
{
 public:
  Target_selector_freebsd(int machine, int size, bool is_big_endian,
			  const char* bfd_name,
			  const char* freebsd_bfd_name)
    : Target_selector(machine, size, is_big_endian, NULL),
      bfd_name_(bfd_name), freebsd_bfd_name_(freebsd_bfd_name)
  { }

 protected:
  // If we see a FreeBSD input file, mark the output file as using
  // FreeBSD.
  virtual Target*
  do_recognize(int, int osabi, int)
  {
    Target* ret = this->instantiate_target();
    if (osabi == elfcpp::ELFOSABI_FREEBSD)
      this->set_osabi(ret);
    return ret;
  }
  
  // Recognize two names.
  virtual Target*
  do_recognize_by_name(const char* name)
  {
    if (strcmp(name, this->bfd_name_) == 0)
      return this->instantiate_target();
    else if (strcmp(name, this->freebsd_bfd_name_) == 0)
      {
	Target* ret = this->instantiate_target();
	this->set_osabi(ret);
	return ret;
      }
    else
      return NULL;
  }

  // Print both names in --help output.
  virtual void
  do_supported_names(std::vector<const char*>* names)
  {
    names->push_back(this->bfd_name_);
    names->push_back(this->freebsd_bfd_name_);
  }

 private:
  // Set the OSABI field.  This is quite ugly.
  void
  set_osabi(Target* target)
  {
    if (this->get_size() == 32)
      {
	if (this->is_big_endian())
	  static_cast<Target_freebsd<32, true>*>(target)->
	    set_osabi(elfcpp::ELFOSABI_FREEBSD);
	else
	  static_cast<Target_freebsd<32, false>*>(target)->
	    set_osabi(elfcpp::ELFOSABI_FREEBSD);
      }
    else if (this->get_size() == 64)
      {
	if (this->is_big_endian())
	  static_cast<Target_freebsd<64, true>*>(target)->
	    set_osabi(elfcpp::ELFOSABI_FREEBSD);
	else
	  static_cast<Target_freebsd<64, false>*>(target)->
	    set_osabi(elfcpp::ELFOSABI_FREEBSD);
      }
    else
      gold_unreachable();
  }

  // The BFD name for the non-Freebsd target.
  const char* bfd_name_;
  // The BFD name for the Freebsd target.
  const char* freebsd_bfd_name_;
};

} // end namespace gold

#endif // !defined(GOLD_FREEBSD_H)
