OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [freebsd.h] - Diff between revs 27 and 159

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 27 Rev 159
Line 1... Line 1...
// freebsd.h -- FreeBSD support for gold    -*- C++ -*-
// freebsd.h -- FreeBSD support for gold    -*- C++ -*-
 
 
// Copyright 2009 Free Software Foundation, Inc.
// Copyright 2009, 2011 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// Written by Ian Lance Taylor <iant@google.com>.
 
 
// This file is part of gold.
// This file is part of gold.
 
 
// This program is free software; you can redistribute it and/or modify
// This program is free software; you can redistribute it and/or modify
Line 28... Line 28...
 
 
namespace gold
namespace gold
{
{
 
 
// FreeBSD 4.1 and later wants the EI_OSABI field in the ELF header to
// 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
// be set to ELFOSABI_FREEBSD.  This is a target selector for targets
// which supports that.  The real target would be a subclass of this
// which permit combining both FreeBSD and non-FreeBSD object files.
// 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<size>::ehdr_size);
 
 
 
      elfcpp::Ehdr<size, 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<size, 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
class Target_selector_freebsd : public Target_selector
{
{
 public:
 public:
  Target_selector_freebsd(int machine, int size, bool is_big_endian,
  Target_selector_freebsd(int machine, int size, bool is_big_endian,
                          const char* bfd_name,
                          const char* bfd_name,
                          const char* freebsd_bfd_name)
                          const char* freebsd_bfd_name,
    : Target_selector(machine, size, is_big_endian, NULL),
                          const char* emulation)
 
    : Target_selector(machine, size, is_big_endian, NULL, emulation),
      bfd_name_(bfd_name), freebsd_bfd_name_(freebsd_bfd_name)
      bfd_name_(bfd_name), freebsd_bfd_name_(freebsd_bfd_name)
  { }
  { }
 
 
 protected:
 protected:
  // If we see a FreeBSD input file, mark the output file as using
  // If we see a FreeBSD input file, mark the output file as using
Line 100... Line 50...
  virtual Target*
  virtual Target*
  do_recognize(int, int osabi, int)
  do_recognize(int, int osabi, int)
  {
  {
    Target* ret = this->instantiate_target();
    Target* ret = this->instantiate_target();
    if (osabi == elfcpp::ELFOSABI_FREEBSD)
    if (osabi == elfcpp::ELFOSABI_FREEBSD)
      this->set_osabi(ret);
      ret->set_osabi(static_cast<elfcpp::ELFOSABI>(osabi));
    return ret;
    return ret;
  }
  }
 
 
  // Recognize two names.
  // Recognize two names.
  virtual Target*
  virtual Target*
  do_recognize_by_name(const char* name)
  do_recognize_by_bfd_name(const char* name)
  {
  {
    if (strcmp(name, this->bfd_name_) == 0)
    if (strcmp(name, this->bfd_name_) == 0)
      return this->instantiate_target();
      return this->instantiate_target();
    else if (strcmp(name, this->freebsd_bfd_name_) == 0)
    else if (strcmp(name, this->freebsd_bfd_name_) == 0)
      {
      {
        Target* ret = this->instantiate_target();
        Target* ret = this->instantiate_target();
        this->set_osabi(ret);
        ret->set_osabi(elfcpp::ELFOSABI_FREEBSD);
        return ret;
        return ret;
      }
      }
    else
    else
      return NULL;
      return NULL;
  }
  }
 
 
  // Print both names in --help output.
  // Print both names in --help output.
  virtual void
  virtual void
  do_supported_names(std::vector<const char*>* names)
  do_supported_bfd_names(std::vector<const char*>* names)
  {
  {
    names->push_back(this->bfd_name_);
    names->push_back(this->bfd_name_);
    names->push_back(this->freebsd_bfd_name_);
    names->push_back(this->freebsd_bfd_name_);
  }
  }
 
 
 private:
  // Return appropriate BFD name.
  // Set the OSABI field.  This is quite ugly.
  virtual const char*
  void
  do_target_bfd_name(const Target* target)
  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())
    if (!this->is_our_target(target))
          static_cast<Target_freebsd<64, true>*>(target)->
      return NULL;
            set_osabi(elfcpp::ELFOSABI_FREEBSD);
    return (target->osabi() == elfcpp::ELFOSABI_FREEBSD
        else
            ? this->freebsd_bfd_name_
          static_cast<Target_freebsd<64, false>*>(target)->
            : this->bfd_name_);
            set_osabi(elfcpp::ELFOSABI_FREEBSD);
 
      }
 
    else
 
      gold_unreachable();
 
  }
  }
 
 
 
 private:
  // The BFD name for the non-Freebsd target.
  // The BFD name for the non-Freebsd target.
  const char* bfd_name_;
  const char* bfd_name_;
  // The BFD name for the Freebsd target.
  // The BFD name for the Freebsd target.
  const char* freebsd_bfd_name_;
  const char* freebsd_bfd_name_;
};
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.