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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [arm.cc] - Diff between revs 159 and 163

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

Rev 159 Rev 163
Line 2073... Line 2073...
            return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0;
            return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0;
          // These should have been converted to something else above.
          // These should have been converted to something else above.
          case elfcpp::R_ARM_TARGET1:
          case elfcpp::R_ARM_TARGET1:
          case elfcpp::R_ARM_TARGET2:
          case elfcpp::R_ARM_TARGET2:
            gold_unreachable();
            gold_unreachable();
          // Relocations that write full 32 bits.
          // Relocations that write full 32 bits and
 
          // have alignment of 1.
          case elfcpp::R_ARM_ABS32:
          case elfcpp::R_ARM_ABS32:
          case elfcpp::R_ARM_REL32:
          case elfcpp::R_ARM_REL32:
          case elfcpp::R_ARM_SBREL32:
          case elfcpp::R_ARM_SBREL32:
          case elfcpp::R_ARM_GOTOFF32:
          case elfcpp::R_ARM_GOTOFF32:
          case elfcpp::R_ARM_BASE_PREL:
          case elfcpp::R_ARM_BASE_PREL:
Line 2091... Line 2092...
          case elfcpp::R_ARM_TLS_GD32:
          case elfcpp::R_ARM_TLS_GD32:
          case elfcpp::R_ARM_TLS_LDM32:
          case elfcpp::R_ARM_TLS_LDM32:
          case elfcpp::R_ARM_TLS_LDO32:
          case elfcpp::R_ARM_TLS_LDO32:
          case elfcpp::R_ARM_TLS_IE32:
          case elfcpp::R_ARM_TLS_IE32:
          case elfcpp::R_ARM_TLS_LE32:
          case elfcpp::R_ARM_TLS_LE32:
            return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4;
            return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4_UNALIGNED;
          default:
          default:
            // For all other static relocations, return RELOC_SPECIAL.
            // For all other static relocations, return RELOC_SPECIAL.
            return Relocatable_relocs::RELOC_SPECIAL;
            return Relocatable_relocs::RELOC_SPECIAL;
          }
          }
      }
      }
Line 2175... Line 2176...
    : Sized_target<32, big_endian>(&arm_info),
    : Sized_target<32, big_endian>(&arm_info),
      got_(NULL), plt_(NULL), got_plt_(NULL), rel_dyn_(NULL),
      got_(NULL), plt_(NULL), got_plt_(NULL), rel_dyn_(NULL),
      copy_relocs_(elfcpp::R_ARM_COPY), dynbss_(NULL),
      copy_relocs_(elfcpp::R_ARM_COPY), dynbss_(NULL),
      got_mod_index_offset_(-1U), tls_base_symbol_defined_(false),
      got_mod_index_offset_(-1U), tls_base_symbol_defined_(false),
      stub_tables_(), stub_factory_(Stub_factory::get_instance()),
      stub_tables_(), stub_factory_(Stub_factory::get_instance()),
      may_use_blx_(false), should_force_pic_veneer_(false),
      should_force_pic_veneer_(false),
      arm_input_section_map_(), attributes_section_data_(NULL),
      arm_input_section_map_(), attributes_section_data_(NULL),
      fix_cortex_a8_(false), cortex_a8_relocs_info_()
      fix_cortex_a8_(false), cortex_a8_relocs_info_()
  { }
  { }
 
 
  // Whether we can use BLX.
 
  bool
 
  may_use_blx() const
 
  { return this->may_use_blx_; }
 
 
 
  // Set use-BLX flag.
 
  void
 
  set_may_use_blx(bool value)
 
  { this->may_use_blx_ = value; }
 
 
 
  // Whether we force PCI branch veneers.
  // Whether we force PCI branch veneers.
  bool
  bool
  should_force_pic_veneer() const
  should_force_pic_veneer() const
  { return this->should_force_pic_veneer_; }
  { return this->should_force_pic_veneer_; }
 
 
Line 2252... Line 2243...
    return (arch == elfcpp::TAG_CPU_ARCH_V6T2
    return (arch == elfcpp::TAG_CPU_ARCH_V6T2
            || arch == elfcpp::TAG_CPU_ARCH_V7
            || arch == elfcpp::TAG_CPU_ARCH_V7
            || arch == elfcpp::TAG_CPU_ARCH_V7E_M);
            || arch == elfcpp::TAG_CPU_ARCH_V7E_M);
  }
  }
 
 
 
  // Whether we have v4T interworking instructions available.
 
  bool
 
  may_use_v4t_interworking() const
 
  {
 
    Object_attribute* attr =
 
      this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
 
    int arch = attr->int_value();
 
    return (arch != elfcpp::TAG_CPU_ARCH_PRE_V4
 
            && arch != elfcpp::TAG_CPU_ARCH_V4);
 
  }
 
 
 
  // Whether we have v5T interworking instructions available.
 
  bool
 
  may_use_v5t_interworking() const
 
  {
 
    Object_attribute* attr =
 
      this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
 
    int arch = attr->int_value();
 
    if (parameters->options().fix_arm1176())
 
      return (arch == elfcpp::TAG_CPU_ARCH_V6T2
 
              || arch == elfcpp::TAG_CPU_ARCH_V7
 
              || arch == elfcpp::TAG_CPU_ARCH_V6_M
 
              || arch == elfcpp::TAG_CPU_ARCH_V6S_M
 
              || arch == elfcpp::TAG_CPU_ARCH_V7E_M);
 
    else
 
      return (arch != elfcpp::TAG_CPU_ARCH_PRE_V4
 
              && arch != elfcpp::TAG_CPU_ARCH_V4
 
              && arch != elfcpp::TAG_CPU_ARCH_V4T);
 
  }
 
 
  // Process the relocations to determine unreferenced sections for 
  // Process the relocations to determine unreferenced sections for 
  // garbage collection.
  // garbage collection.
  void
  void
  gc_process_relocs(Symbol_table* symtab,
  gc_process_relocs(Symbol_table* symtab,
                    Layout* layout,
                    Layout* layout,
Line 2920... Line 2941...
  bool tls_base_symbol_defined_;
  bool tls_base_symbol_defined_;
  // Vector of Stub_tables created.
  // Vector of Stub_tables created.
  Stub_table_list stub_tables_;
  Stub_table_list stub_tables_;
  // Stub factory.
  // Stub factory.
  const Stub_factory &stub_factory_;
  const Stub_factory &stub_factory_;
  // Whether we can use BLX.
 
  bool may_use_blx_;
 
  // Whether we force PIC branch veneers.
  // Whether we force PIC branch veneers.
  bool should_force_pic_veneer_;
  bool should_force_pic_veneer_;
  // Map for locating Arm_input_sections.
  // Map for locating Arm_input_sections.
  Arm_input_section_map arm_input_section_map_;
  Arm_input_section_map arm_input_section_map_;
  // Attributes section data in output.
  // Attributes section data in output.
Line 3948... Line 3967...
  Valtype branch_target = psymval->value(object, addend);
  Valtype branch_target = psymval->value(object, addend);
  int32_t branch_offset = branch_target - address;
  int32_t branch_offset = branch_target - address;
 
 
  // We need a stub if the branch offset is too large or if we need
  // We need a stub if the branch offset is too large or if we need
  // to switch mode.
  // to switch mode.
  bool may_use_blx = arm_target->may_use_blx();
  bool may_use_blx = arm_target->may_use_v5t_interworking();
  Reloc_stub* stub = NULL;
  Reloc_stub* stub = NULL;
 
 
  if (!parameters->options().relocatable()
  if (!parameters->options().relocatable()
      && (utils::has_overflow<26>(branch_offset)
      && (utils::has_overflow<26>(branch_offset)
          || ((thumb_bit != 0)
          || ((thumb_bit != 0)
Line 4079... Line 4098...
 
 
  int32_t addend = This::thumb32_branch_offset(upper_insn, lower_insn);
  int32_t addend = This::thumb32_branch_offset(upper_insn, lower_insn);
  Arm_address branch_target = psymval->value(object, addend);
  Arm_address branch_target = psymval->value(object, addend);
 
 
  // For BLX, bit 1 of target address comes from bit 1 of base address.
  // For BLX, bit 1 of target address comes from bit 1 of base address.
  bool may_use_blx = arm_target->may_use_blx();
  bool may_use_blx = arm_target->may_use_v5t_interworking();
  if (thumb_bit == 0 && may_use_blx)
  if (thumb_bit == 0 && may_use_blx)
    branch_target = utils::bit_select(branch_target, address, 0x2);
    branch_target = utils::bit_select(branch_target, address, 0x2);
 
 
  int32_t branch_offset = branch_target - address;
  int32_t branch_offset = branch_target - address;
 
 
Line 4462... Line 4481...
  bool thumb_only;
  bool thumb_only;
  if (parameters->target().is_big_endian())
  if (parameters->target().is_big_endian())
    {
    {
      const Target_arm<true>* big_endian_target =
      const Target_arm<true>* big_endian_target =
        Target_arm<true>::default_target();
        Target_arm<true>::default_target();
      may_use_blx = big_endian_target->may_use_blx();
      may_use_blx = big_endian_target->may_use_v5t_interworking();
      should_force_pic_veneer = big_endian_target->should_force_pic_veneer();
      should_force_pic_veneer = big_endian_target->should_force_pic_veneer();
      thumb2 = big_endian_target->using_thumb2();
      thumb2 = big_endian_target->using_thumb2();
      thumb_only = big_endian_target->using_thumb_only();
      thumb_only = big_endian_target->using_thumb_only();
    }
    }
  else
  else
    {
    {
      const Target_arm<false>* little_endian_target =
      const Target_arm<false>* little_endian_target =
        Target_arm<false>::default_target();
        Target_arm<false>::default_target();
      may_use_blx = little_endian_target->may_use_blx();
      may_use_blx = little_endian_target->may_use_v5t_interworking();
      should_force_pic_veneer = little_endian_target->should_force_pic_veneer();
      should_force_pic_veneer = little_endian_target->should_force_pic_veneer();
      thumb2 = little_endian_target->using_thumb2();
      thumb2 = little_endian_target->using_thumb2();
      thumb_only = little_endian_target->using_thumb_only();
      thumb_only = little_endian_target->using_thumb_only();
    }
    }
 
 
Line 8602... Line 8621...
  // at this moment.  This happens if there is no attributes sections in all
  // at this moment.  This happens if there is no attributes sections in all
  // inputs.
  // inputs.
  if (this->attributes_section_data_ == NULL)
  if (this->attributes_section_data_ == NULL)
    this->attributes_section_data_ = new Attributes_section_data(NULL, 0);
    this->attributes_section_data_ = new Attributes_section_data(NULL, 0);
 
 
  // Check BLX use.
 
  const Object_attribute* cpu_arch_attr =
  const Object_attribute* cpu_arch_attr =
    this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
    this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
  if (cpu_arch_attr->int_value() > elfcpp::TAG_CPU_ARCH_V4)
 
    this->set_may_use_blx(true);
 
 
 
  // Check if we need to use Cortex-A8 workaround.
  // Check if we need to use Cortex-A8 workaround.
  if (parameters->options().user_set_fix_cortex_a8())
  if (parameters->options().user_set_fix_cortex_a8())
    this->fix_cortex_a8_ = parameters->options().fix_cortex_a8();
    this->fix_cortex_a8_ = parameters->options().fix_cortex_a8();
  else
  else
    {
    {
Line 8628... Line 8643...
 
 
  // Check if we can use V4BX interworking.
  // Check if we can use V4BX interworking.
  // The V4BX interworking stub contains BX instruction,
  // The V4BX interworking stub contains BX instruction,
  // which is not specified for some profiles.
  // which is not specified for some profiles.
  if (this->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING
  if (this->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING
      && !this->may_use_blx())
      && !this->may_use_v4t_interworking())
    gold_error(_("unable to provide V4BX reloc interworking fix up; "
    gold_error(_("unable to provide V4BX reloc interworking fix up; "
                 "the target profile does not support BX instruction"));
                 "the target profile does not support BX instruction"));
 
 
  // Fill in some more dynamic tags.
  // Fill in some more dynamic tags.
  const Reloc_section* rel_plt = (this->plt_ == NULL
  const Reloc_section* rel_plt = (this->plt_ == NULL
Line 9331... Line 9346...
              Arm_address got_entry =
              Arm_address got_entry =
                target->got_plt_section()->address() + got_offset;
                target->got_plt_section()->address() + got_offset;
 
 
              // Relocate the field with the PC relative offset of the pair of
              // Relocate the field with the PC relative offset of the pair of
              // GOT entries.
              // GOT entries.
              RelocFuncs::pcrel32(view, got_entry, address);
              RelocFuncs::pcrel32_unaligned(view, got_entry, address);
              return ArmRelocFuncs::STATUS_OKAY;
              return ArmRelocFuncs::STATUS_OKAY;
            }
            }
        }
        }
      break;
      break;
 
 
Line 9350... Line 9365...
          Arm_address got_entry =
          Arm_address got_entry =
            target->got_plt_section()->address() + got_offset;
            target->got_plt_section()->address() + got_offset;
 
 
          // Relocate the field with the PC relative offset of the pair of
          // Relocate the field with the PC relative offset of the pair of
          // GOT entries.
          // GOT entries.
          RelocFuncs::pcrel32(view, got_entry, address);
          RelocFuncs::pcrel32_unaligned(view, got_entry, address);
          return ArmRelocFuncs::STATUS_OKAY;
          return ArmRelocFuncs::STATUS_OKAY;
        }
        }
      break;
      break;
 
 
    case elfcpp::R_ARM_TLS_LDO32:       // Alternate local-dynamic
    case elfcpp::R_ARM_TLS_LDO32:       // Alternate local-dynamic
      RelocFuncs::rel32(view, value);
      RelocFuncs::rel32_unaligned(view, value);
      return ArmRelocFuncs::STATUS_OKAY;
      return ArmRelocFuncs::STATUS_OKAY;
 
 
    case elfcpp::R_ARM_TLS_IE32:        // Initial-exec
    case elfcpp::R_ARM_TLS_IE32:        // Initial-exec
      if (optimized_type == tls::TLSOPT_NONE)
      if (optimized_type == tls::TLSOPT_NONE)
        {
        {
Line 9385... Line 9400...
 
 
          Arm_address got_entry =
          Arm_address got_entry =
            target->got_plt_section()->address() + got_offset;
            target->got_plt_section()->address() + got_offset;
 
 
          // Relocate the field with the PC relative offset of the GOT entry.
          // Relocate the field with the PC relative offset of the GOT entry.
          RelocFuncs::pcrel32(view, got_entry, address);
          RelocFuncs::pcrel32_unaligned(view, got_entry, address);
          return ArmRelocFuncs::STATUS_OKAY;
          return ArmRelocFuncs::STATUS_OKAY;
        }
        }
      break;
      break;
 
 
    case elfcpp::R_ARM_TLS_LE32:        // Local-exec
    case elfcpp::R_ARM_TLS_LE32:        // Local-exec
Line 9401... Line 9416...
 
 
          // $tp points to the TCB, which is followed by the TLS, so we
          // $tp points to the TCB, which is followed by the TLS, so we
          // need to add TCB size to the offset.
          // need to add TCB size to the offset.
          Arm_address aligned_tcb_size =
          Arm_address aligned_tcb_size =
            align_address(ARM_TCB_SIZE, tls_segment->maximum_alignment());
            align_address(ARM_TCB_SIZE, tls_segment->maximum_alignment());
          RelocFuncs::rel32(view, value + aligned_tcb_size);
          RelocFuncs::rel32_unaligned(view, value + aligned_tcb_size);
 
 
        }
        }
      return ArmRelocFuncs::STATUS_OKAY;
      return ArmRelocFuncs::STATUS_OKAY;
 
 
    default:
    default:
Line 9991... Line 10006...
    const std::string& name,
    const std::string& name,
    Input_file* input_file,
    Input_file* input_file,
    off_t offset, const elfcpp::Ehdr<32, big_endian>& ehdr)
    off_t offset, const elfcpp::Ehdr<32, big_endian>& ehdr)
{
{
  int et = ehdr.get_e_type();
  int et = ehdr.get_e_type();
  if (et == elfcpp::ET_REL)
  // ET_EXEC files are valid input for --just-symbols/-R,
 
  // and we treat them as relocatable objects.
 
  if (et == elfcpp::ET_REL
 
      || (et == elfcpp::ET_EXEC && input_file->just_symbols()))
    {
    {
      Arm_relobj<big_endian>* obj =
      Arm_relobj<big_endian>* obj =
        new Arm_relobj<big_endian>(name, input_file, offset, ehdr);
        new Arm_relobj<big_endian>(name, input_file, offset, ehdr);
      obj->setup();
      obj->setup();
      return obj;
      return obj;
Line 11795... Line 11813...
 
 
              // The original instruction is a BL, but the target is
              // The original instruction is a BL, but the target is
              // an ARM instruction.  If we were not making a stub,
              // an ARM instruction.  If we were not making a stub,
              // the BL would have been converted to a BLX.  Use the
              // the BL would have been converted to a BLX.  Use the
              // BLX stub instead in that case.
              // BLX stub instead in that case.
              if (this->may_use_blx() && force_target_arm
              if (this->may_use_v5t_interworking() && force_target_arm
                  && stub_type == arm_stub_a8_veneer_bl)
                  && stub_type == arm_stub_a8_veneer_bl)
                {
                {
                  stub_type = arm_stub_a8_veneer_blx;
                  stub_type = arm_stub_a8_veneer_blx;
                  is_blx = true;
                  is_blx = true;
                  is_bl = false;
                  is_bl = false;

powered by: WebSVN 2.1.0

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