2009-05-28 Doug Kwan <dougkwan@google.com>
authorDoug Kwan <dougkwan@google.com>
Fri, 29 May 2009 00:15:12 +0000 (00:15 +0000)
committerDoug Kwan <dougkwan@google.com>
Fri, 29 May 2009 00:15:12 +0000 (00:15 +0000)
        * configure.ac: Support gold for target arm*-*-*.
        * configure: Regenerate.
        * gold/Makefile.am (TARGETSOURCES): Add arm.cc.
        (ALL_TARGETOBJECTS): Add arm.$(OBJEXT)
        * gold/Makefile.in: Regenerate.
        * gold/arm.cc: New file.
        * gold/configure.tgt: Add armbe*-*-*, armeb*-*-* and arm*-*-* targets.

ChangeLog
configure
configure.ac
gold/ChangeLog
gold/Makefile.am
gold/Makefile.in
gold/arm.cc [new file with mode: 0644]
gold/configure.tgt

index b91cfce04319ddded7fc482d980d420b16d991ac..adacc3d17923ada175f10d7938eeaf8cec926654 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-05-28  Doug Kwan  <dougkwan@google.com>
+
+       * configure.ac: Support gold for target arm*-*-*.
+       * configure: Regenerate.
+
 2009-05-27  Alexandre Oliva  <aoliva@redhat.com>
 
        * Makefile.tpl (all): Avoid harmless warning in make all when
index 8559109b63b0052c8eb2bfd9a79b3dc6eefd619b..d750b42bf2edaa234b66aaee006b06e9a26ce005 100755 (executable)
--- a/configure
+++ b/configure
@@ -2077,7 +2077,7 @@ if test "${ENABLE_GOLD}" = "yes"; then
   if test "$is_elf" = "yes"; then
     # Check for target supported by gold.
     case "${target}" in
-      i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-*)
+      i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*)
         configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`"
         ;;
     esac
index ee63082d62c21f51272e4286ebc76237cf0a31f6..ba45bd5d80d43af8b02b520116b27d9a9770c6a4 100644 (file)
@@ -318,7 +318,7 @@ if test "${ENABLE_GOLD}" = "yes"; then
   if test "$is_elf" = "yes"; then
     # Check for target supported by gold.
     case "${target}" in
-      i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-*)
+      i?86-*-* | x86_64-*-* | sparc*-*-* | powerpc*-*-* | arm*-*-*)
         configdirs="`echo " ${configdirs} " | sed -e 's/ ld / gold /'`"
         ;;
     esac
index 00f8464d4aebc169c24b426d5dc78e3ed93d137c..1e03ba4ce73a154e6f8da3b27f6cd132f3886eeb 100644 (file)
@@ -1,3 +1,11 @@
+2009-05-28  Doug Kwan  <dougkwan@google.com>
+
+       * Makefile.am (TARGETSOURCES): Add arm.cc.
+       (ALL_TARGETOBJECTS): Add arm.$(OBJEXT)
+       * Makefile.in: Regenerate.
+       * arm.cc: New file.
+       * configure.tgt: Add armbe*-*-*, armeb*-*-* and arm*-*-* targets.
+
 2009-05-26  Doug Kwan  <dougkwan@google.com>
 
        * options.cc (General_options::parse_exclude_libs).  Fix a comment.
index 360cb7f3fe4db781a9ac19ee135925323c0db343..c0ab159f230c47804bb3952f623343ddb1c2c146 100644 (file)
@@ -123,10 +123,11 @@ YFILES = \
 EXTRA_DIST = yyscript.c yyscript.h
 
 TARGETSOURCES = \
-       i386.cc x86_64.cc sparc.cc powerpc.cc
+       i386.cc x86_64.cc sparc.cc powerpc.cc arm.cc
 
 ALL_TARGETOBJS = \
-       i386.$(OBJEXT) x86_64.$(OBJEXT) sparc.$(OBJEXT) powerpc.$(OBJEXT)
+       i386.$(OBJEXT) x86_64.$(OBJEXT) sparc.$(OBJEXT) powerpc.$(OBJEXT) \
+       arm.$(OBJEXT)
 
 libgold_a_SOURCES = $(CCFILES) $(HFILES) $(YFILES)
 
index fe3474de868686c94eec1b2b5c9532739218d50b..3e6b7254d0694e9f72aa902426425e532e442190 100644 (file)
@@ -406,10 +406,11 @@ YFILES = \
 
 EXTRA_DIST = yyscript.c yyscript.h
 TARGETSOURCES = \
-       i386.cc x86_64.cc sparc.cc powerpc.cc
+       i386.cc x86_64.cc sparc.cc powerpc.cc arm.cc
 
 ALL_TARGETOBJS = \
-       i386.$(OBJEXT) x86_64.$(OBJEXT) sparc.$(OBJEXT) powerpc.$(OBJEXT)
+       i386.$(OBJEXT) x86_64.$(OBJEXT) sparc.$(OBJEXT) powerpc.$(OBJEXT) \
+       arm.$(OBJEXT)
 
 libgold_a_SOURCES = $(CCFILES) $(HFILES) $(YFILES)
 sources_var = main.cc
diff --git a/gold/arm.cc b/gold/arm.cc
new file mode 100644 (file)
index 0000000..580b3ef
--- /dev/null
@@ -0,0 +1,672 @@
+// arm.cc -- arm target support for gold.
+
+// Copyright 2009 Free Software Foundation, Inc.
+// Written by Doug Kwan <dougkwan@google.com> based on the i386 code
+// 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 "gold.h"
+
+#include <cstring>
+#include <limits>
+#include <cstdio>
+#include <string>
+
+#include "elfcpp.h"
+#include "parameters.h"
+#include "reloc.h"
+#include "arm.h"
+#include "object.h"
+#include "symtab.h"
+#include "layout.h"
+#include "output.h"
+#include "copy-relocs.h"
+#include "target.h"
+#include "target-reloc.h"
+#include "target-select.h"
+#include "tls.h"
+#include "defstd.h"
+
+namespace
+{
+
+using namespace gold;
+
+// The arm target class.
+//
+// This is a very simple port of gold for ARM-EABI.  It is intended for
+// supporting Android only for the time being.  Only these relocation types
+// are supported.
+//
+// R_ARM_NONE
+// R_ARM_ABS32
+// R_ARM_REL32
+// R_ARM_THM_CALL
+// R_ARM_COPY
+// R_ARM_GLOB_DAT
+// R_ARM_BASE_PREL
+// R_ARM_JUMP_SLOT
+// R_ARM_RELATIVE
+// R_ARM_GOTOFF32
+// R_ARM_GOT_BREL
+// R_ARM_PLT32
+// R_ARM_CALL
+// R_ARM_JUMP24
+// R_ARM_TARGET1
+// R_ARM_PREL31
+// 
+// Coming soon (pending patches):
+// - Support for dynamic symbols (GOT, PLT and etc).
+// - Local scanner
+// - Global scanner
+// - Relocation
+// - Defining section symbols __exidx_start and __exidx_stop.
+// - Support interworking.
+// - Mergeing all .ARM.xxx.yyy sections into .ARM.xxx.  Currently, they
+//   are incorrectly merged into an .ARM section.
+//
+// TODOs:
+// - Create a PT_ARM_EXIDX program header for a shared object that
+//   might throw an exception.
+// - Support more relocation types as needed. 
+
+template<bool big_endian>
+class Target_arm : public Sized_target<32, big_endian>
+{
+ public:
+  typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, big_endian>
+    Reloc_section;
+
+  Target_arm()
+    : Sized_target<32, big_endian>(&arm_info)
+  { }
+
+  // Process the relocations to determine unreferenced sections for 
+  // garbage collection.
+  void
+  gc_process_relocs(const General_options& options,
+                   Symbol_table* symtab,
+                   Layout* layout,
+                   Sized_relobj<32, big_endian>* object,
+                   unsigned int data_shndx,
+                   unsigned int sh_type,
+                   const unsigned char* prelocs,
+                   size_t reloc_count,
+                   Output_section* output_section,
+                   bool needs_special_offset_handling,
+                   size_t local_symbol_count,
+                   const unsigned char* plocal_symbols);
+
+  // Scan the relocations to look for symbol adjustments.
+  void
+  scan_relocs(const General_options& options,
+             Symbol_table* symtab,
+             Layout* layout,
+             Sized_relobj<32, big_endian>* object,
+             unsigned int data_shndx,
+             unsigned int sh_type,
+             const unsigned char* prelocs,
+             size_t reloc_count,
+             Output_section* output_section,
+             bool needs_special_offset_handling,
+             size_t local_symbol_count,
+             const unsigned char* plocal_symbols);
+
+  // Finalize the sections.
+  void
+  do_finalize_sections(Layout*);
+
+  // Return the value to use for a dynamic which requires special
+  // treatment.
+  uint64_t
+  do_dynsym_value(const Symbol*) const;
+
+  // Relocate a section.
+  void
+  relocate_section(const Relocate_info<32, big_endian>*,
+                  unsigned int sh_type,
+                  const unsigned char* prelocs,
+                  size_t reloc_count,
+                  Output_section* output_section,
+                  bool needs_special_offset_handling,
+                  unsigned char* view,
+                  elfcpp::Elf_types<32>::Elf_Addr view_address,
+                  section_size_type view_size);
+
+  // Scan the relocs during a relocatable link.
+  void
+  scan_relocatable_relocs(const General_options& options,
+                         Symbol_table* symtab,
+                         Layout* layout,
+                         Sized_relobj<32, big_endian>* object,
+                         unsigned int data_shndx,
+                         unsigned int sh_type,
+                         const unsigned char* prelocs,
+                         size_t reloc_count,
+                         Output_section* output_section,
+                         bool needs_special_offset_handling,
+                         size_t local_symbol_count,
+                         const unsigned char* plocal_symbols,
+                         Relocatable_relocs*);
+
+  // Relocate a section during a relocatable link.
+  void
+  relocate_for_relocatable(const Relocate_info<32, big_endian>*,
+                          unsigned int sh_type,
+                          const unsigned char* prelocs,
+                          size_t reloc_count,
+                          Output_section* output_section,
+                          off_t offset_in_output_section,
+                          const Relocatable_relocs*,
+                          unsigned char* view,
+                          elfcpp::Elf_types<32>::Elf_Addr view_address,
+                          section_size_type view_size,
+                          unsigned char* reloc_view,
+                          section_size_type reloc_view_size);
+
+  // Return whether SYM is defined by the ABI.
+  bool
+  do_is_defined_by_abi(Symbol* sym) const
+  { return strcmp(sym->name(), "__tls_get_addr") == 0; }
+
+  // Map platform-specific reloc types
+  static unsigned int
+  get_real_reloc_type (unsigned int r_type);
+
+ private:
+  // The class which scans relocations.
+  class Scan
+  {
+   public:
+    Scan()
+    { }
+
+    inline void
+    local(const General_options& options, Symbol_table* symtab,
+         Layout* layout, Target_arm* target,
+         Sized_relobj<32, big_endian>* object,
+         unsigned int data_shndx,
+         Output_section* output_section,
+         const elfcpp::Rel<32, big_endian>& reloc, unsigned int r_type,
+         const elfcpp::Sym<32, big_endian>& lsym);
+
+    inline void
+    global(const General_options& options, Symbol_table* symtab,
+          Layout* layout, Target_arm* target,
+          Sized_relobj<32, big_endian>* object,
+          unsigned int data_shndx,
+          Output_section* output_section,
+          const elfcpp::Rel<32, big_endian>& reloc, unsigned int r_type,
+          Symbol* gsym);
+
+   private:
+    static void
+    unsupported_reloc_local(Sized_relobj<32, big_endian>*,
+                           unsigned int r_type);
+
+    static void
+    unsupported_reloc_global(Sized_relobj<32, big_endian>*,
+                            unsigned int r_type, Symbol*);
+  };
+
+  // The class which implements relocation.
+  class Relocate
+  {
+   public:
+    Relocate()
+    { }
+
+    ~Relocate()
+    { }
+
+    // Do a relocation.  Return false if the caller should not issue
+    // any warnings about this relocation.
+    inline bool
+    relocate(const Relocate_info<32, big_endian>*, Target_arm*,
+            Output_section*,  size_t relnum,
+            const elfcpp::Rel<32, big_endian>&,
+            unsigned int r_type, const Sized_symbol<32>*,
+            const Symbol_value<32>*,
+            unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
+            section_size_type);
+  };
+
+  // A class which returns the size required for a relocation type,
+  // used while scanning relocs during a relocatable link.
+  class Relocatable_size_for_reloc
+  {
+   public:
+    unsigned int
+    get_size_for_reloc(unsigned int, Relobj*);
+  };
+
+  // Information about this specific target which we pass to the
+  // general Target structure.
+  static const Target::Target_info arm_info;
+};
+
+template<bool big_endian>
+const Target::Target_info Target_arm<big_endian>::arm_info =
+{
+  32,                  // size
+  big_endian,          // is_big_endian
+  elfcpp::EM_ARM,      // machine_code
+  false,               // has_make_symbol
+  false,               // has_resolve
+  false,               // has_code_fill
+  true,                        // is_default_stack_executable
+  '\0',                        // wrap_char
+  "/usr/lib/libc.so.1",        // dynamic_linker
+  0x8000,              // default_text_segment_address
+  0x1000,              // abi_pagesize (overridable by -z max-page-size)
+  0x1000               // common_pagesize (overridable by -z common-page-size)
+};
+
+// Report an unsupported relocation against a local symbol.
+
+template<bool big_endian>
+void
+Target_arm<big_endian>::Scan::unsupported_reloc_local(
+    Sized_relobj<32, big_endian>* object,
+    unsigned int r_type)
+{
+  gold_error(_("%s: unsupported reloc %u against local symbol"),
+            object->name().c_str(), r_type);
+}
+
+// Scan a relocation for a local symbol.
+
+template<bool big_endian>
+inline void
+Target_arm<big_endian>::Scan::local(const General_options&,
+                                   Symbol_table* /* symtab */,
+                                   Layout* /* layout */,
+                                   Target_arm* /* target */,
+                                   Sized_relobj<32, big_endian>* object,
+                                   unsigned int /* data_shndx */,
+                                   Output_section* /* output_section */,
+                                   const elfcpp::Rel<32, big_endian>& /* reloc */,
+                                   unsigned int r_type,
+                                   const elfcpp::Sym<32, big_endian>&)
+{
+  r_type = get_real_reloc_type(r_type);
+  switch (r_type)
+    {
+    case elfcpp::R_ARM_NONE:
+      break;
+
+    default:
+      unsupported_reloc_local(object, r_type);
+      break;
+    }
+}
+
+// Report an unsupported relocation against a global symbol.
+
+template<bool big_endian>
+void
+Target_arm<big_endian>::Scan::unsupported_reloc_global(
+    Sized_relobj<32, big_endian>* object,
+    unsigned int r_type,
+    Symbol* gsym)
+{
+  gold_error(_("%s: unsupported reloc %u against global symbol %s"),
+            object->name().c_str(), r_type, gsym->demangled_name().c_str());
+}
+
+// Scan a relocation for a global symbol.
+
+template<bool big_endian>
+inline void
+Target_arm<big_endian>::Scan::global(const General_options&,
+                                    Symbol_table* /* symtab */,
+                                    Layout* /* layout */,
+                                    Target_arm* /* target */,
+                                    Sized_relobj<32, big_endian>* object,
+                                    unsigned int /* data_shndx */,
+                                    Output_section* /* output_section */,
+                                    const elfcpp::Rel<32, big_endian>& /* reloc */,
+                                    unsigned int r_type,
+                                    Symbol* gsym)
+{
+  r_type = get_real_reloc_type(r_type);
+  switch (r_type)
+    {
+    case elfcpp::R_ARM_NONE:
+      break;
+
+    default:
+      unsupported_reloc_global(object, r_type, gsym);
+      break;
+    }
+}
+
+// Process relocations for gc.
+
+template<bool big_endian>
+void
+Target_arm<big_endian>::gc_process_relocs(const General_options& options,
+                                         Symbol_table* symtab,
+                                         Layout* layout,
+                                         Sized_relobj<32, big_endian>* object,
+                                         unsigned int data_shndx,
+                                         unsigned int,
+                                         const unsigned char* prelocs,
+                                         size_t reloc_count,
+                                         Output_section* output_section,
+                                         bool needs_special_offset_handling,
+                                         size_t local_symbol_count,
+                                         const unsigned char* plocal_symbols)
+{
+  typedef Target_arm<big_endian> Arm;
+  typedef typename Target_arm<big_endian>::Scan Scan;
+
+  gold::gc_process_relocs<32, big_endian, Arm, elfcpp::SHT_REL, Scan>(
+    options,
+    symtab,
+    layout,
+    this,
+    object,
+    data_shndx,
+    prelocs,
+    reloc_count,
+    output_section,
+    needs_special_offset_handling,
+    local_symbol_count,
+    plocal_symbols);
+}
+
+// Scan relocations for a section.
+
+template<bool big_endian>
+void
+Target_arm<big_endian>::scan_relocs(const General_options& options,
+                                   Symbol_table* symtab,
+                                   Layout* layout,
+                                   Sized_relobj<32, big_endian>* object,
+                                   unsigned int data_shndx,
+                                   unsigned int sh_type,
+                                   const unsigned char* prelocs,
+                                   size_t reloc_count,
+                                   Output_section* output_section,
+                                   bool needs_special_offset_handling,
+                                   size_t local_symbol_count,
+                                   const unsigned char* plocal_symbols)
+{
+  typedef typename Target_arm<big_endian>::Scan Scan;
+  if (sh_type == elfcpp::SHT_RELA)
+    {
+      gold_error(_("%s: unsupported RELA reloc section"),
+                object->name().c_str());
+      return;
+    }
+
+  gold::scan_relocs<32, big_endian, Target_arm, elfcpp::SHT_REL, Scan>(
+    options,
+    symtab,
+    layout,
+    this,
+    object,
+    data_shndx,
+    prelocs,
+    reloc_count,
+    output_section,
+    needs_special_offset_handling,
+    local_symbol_count,
+    plocal_symbols);
+}
+
+// Finalize the sections.
+
+template<bool big_endian>
+void
+Target_arm<big_endian>::do_finalize_sections(Layout* /* layout */)
+{
+  gold_unreachable ();
+}
+
+// Perform a relocation.
+
+template<bool big_endian>
+inline bool
+Target_arm<big_endian>::Relocate::relocate(
+    const Relocate_info<32, big_endian>* /* relinfo */,
+    Target_arm* /* target */,
+    Output_section* /* output_section */,
+    size_t /* relnum */,
+    const elfcpp::Rel<32, big_endian>& /* rel */,
+    unsigned int r_type,
+    const Sized_symbol<32>* /* gsym */,
+    const Symbol_value<32>* /* psymval */,
+    unsigned char* /* view */,
+    elfcpp::Elf_types<32>::Elf_Addr /* address */,
+    section_size_type /* view_size */ )
+{
+  switch (r_type)
+    {
+    case elfcpp::R_ARM_NONE:
+      break;
+
+    default:
+      gold_unreachable();
+    }
+
+  return true;
+}
+
+// Relocate section data.
+
+template<bool big_endian>
+void
+Target_arm<big_endian>::relocate_section(
+    const Relocate_info<32, big_endian>* relinfo,
+    unsigned int sh_type,
+    const unsigned char* prelocs,
+    size_t reloc_count,
+    Output_section* output_section,
+    bool needs_special_offset_handling,
+    unsigned char* view,
+    elfcpp::Elf_types<32>::Elf_Addr address,
+    section_size_type view_size)
+{
+  typedef typename Target_arm<big_endian>::Relocate Arm_relocate;
+  gold_assert(sh_type == elfcpp::SHT_REL);
+
+  gold::relocate_section<32, big_endian, Target_arm, elfcpp::SHT_REL,
+                        Arm_relocate>(
+    relinfo,
+    this,
+    prelocs,
+    reloc_count,
+    output_section,
+    needs_special_offset_handling,
+    view,
+    address,
+    view_size);
+}
+
+// Return the size of a relocation while scanning during a relocatable
+// link.
+
+template<bool big_endian>
+unsigned int
+Target_arm<big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
+    unsigned int r_type,
+    Relobj* object)
+{
+  r_type = get_real_reloc_type(r_type);
+  switch (r_type)
+    {
+    case elfcpp::R_ARM_NONE:
+      return 0;
+
+    case elfcpp::R_ARM_ABS32:
+    case elfcpp::R_ARM_REL32:
+    case elfcpp::R_ARM_THM_CALL:
+    case elfcpp::R_ARM_GOTOFF32:
+    case elfcpp::R_ARM_BASE_PREL:
+    case elfcpp::R_ARM_GOT_BREL:
+    case elfcpp::R_ARM_PLT32:
+    case elfcpp::R_ARM_CALL:
+    case elfcpp::R_ARM_JUMP24:
+    case elfcpp::R_ARM_PREL31:
+      return 4;
+
+    case elfcpp::R_ARM_TARGET1:
+      // This should have been mapped to another type already.
+      // Fall through.
+    case elfcpp::R_ARM_COPY:
+    case elfcpp::R_ARM_GLOB_DAT:
+    case elfcpp::R_ARM_JUMP_SLOT:
+    case elfcpp::R_ARM_RELATIVE:
+      // These are relocations which should only be seen by the
+      // dynamic linker, and should never be seen here.
+      gold_error(_("%s: unexpected reloc %u in object file"),
+                object->name().c_str(), r_type);
+      return 0;
+
+    default:
+      object->error(_("unsupported reloc %u in object file"), r_type);
+      return 0;
+    }
+}
+
+// Scan the relocs during a relocatable link.
+
+template<bool big_endian>
+void
+Target_arm<big_endian>::scan_relocatable_relocs(
+    const General_options& options,
+    Symbol_table* symtab,
+    Layout* layout,
+    Sized_relobj<32, big_endian>* object,
+    unsigned int data_shndx,
+    unsigned int sh_type,
+    const unsigned char* prelocs,
+    size_t reloc_count,
+    Output_section* output_section,
+    bool needs_special_offset_handling,
+    size_t local_symbol_count,
+    const unsigned char* plocal_symbols,
+    Relocatable_relocs* rr)
+{
+  gold_assert(sh_type == elfcpp::SHT_REL);
+
+  typedef gold::Default_scan_relocatable_relocs<elfcpp::SHT_REL,
+    Relocatable_size_for_reloc> Scan_relocatable_relocs;
+
+  gold::scan_relocatable_relocs<32, big_endian, elfcpp::SHT_REL,
+      Scan_relocatable_relocs>(
+    options,
+    symtab,
+    layout,
+    object,
+    data_shndx,
+    prelocs,
+    reloc_count,
+    output_section,
+    needs_special_offset_handling,
+    local_symbol_count,
+    plocal_symbols,
+    rr);
+}
+
+// Relocate a section during a relocatable link.
+
+template<bool big_endian>
+void
+Target_arm<big_endian>::relocate_for_relocatable(
+    const Relocate_info<32, big_endian>* relinfo,
+    unsigned int sh_type,
+    const unsigned char* prelocs,
+    size_t reloc_count,
+    Output_section* output_section,
+    off_t offset_in_output_section,
+    const Relocatable_relocs* rr,
+    unsigned char* view,
+    elfcpp::Elf_types<32>::Elf_Addr view_address,
+    section_size_type view_size,
+    unsigned char* reloc_view,
+    section_size_type reloc_view_size)
+{
+  gold_assert(sh_type == elfcpp::SHT_REL);
+
+  gold::relocate_for_relocatable<32, big_endian, elfcpp::SHT_REL>(
+    relinfo,
+    prelocs,
+    reloc_count,
+    output_section,
+    offset_in_output_section,
+    rr,
+    view,
+    view_address,
+    view_size,
+    reloc_view,
+    reloc_view_size);
+}
+
+template<bool big_endian>
+uint64_t
+Target_arm<big_endian>::do_dynsym_value(const Symbol* /*gsym*/) const
+{
+  gold_unreachable ();
+  return 0;
+}
+
+// Map platform-specific relocs to real relocs
+//
+template<bool big_endian>
+unsigned int
+Target_arm<big_endian>::get_real_reloc_type (unsigned int r_type)
+{
+  switch (r_type)
+    {
+    case elfcpp::R_ARM_TARGET1:
+      // This is either R_ARM_ABS32 or R_ARM_REL32;
+      return elfcpp::R_ARM_ABS32;
+
+    case elfcpp::R_ARM_TARGET2:
+      // This can be any reloc type but ususally is R_ARM_GOT_PREL
+      return elfcpp::R_ARM_GOT_PREL;
+
+    default:
+      return r_type;
+    }
+}
+
+// The selector for arm object files.
+
+template<bool big_endian>
+class Target_selector_arm : public Target_selector
+{
+ public:
+  Target_selector_arm()
+    : Target_selector(elfcpp::EM_ARM, 32, big_endian,
+                     (big_endian ? "elf32-bigarm" : "elf32-littlearm"))
+  { }
+
+  Target*
+  do_instantiate_target()
+  { return new Target_arm<big_endian>(); }
+};
+
+Target_selector_arm<false> target_selector_arm;
+Target_selector_arm<true> target_selector_armbe;
+
+} // End anonymous namespace.
index b4ef3763269edd115112558b18c626d96bc3ac90..de6d4f96ee9ef82455e4e0a7ad797f570d03c306 100644 (file)
@@ -104,6 +104,20 @@ powerpc64-*)
   targ_big_endian=true
   targ_extra_big_endian=false
   ;;
+armeb*-*-*|armbe*-*-*)
+ targ_obj=arm
+ targ_machine=EM_ARM
+ targ_size=32
+ targ_big_endian=true
+ targ_extra_big_endian=false
+ ;;
+arm*-*-*)
+ targ_obj=arm
+ targ_machine=EM_ARM
+ targ_size=32
+ targ_big_endian=false
+ targ_extra_big_endian=true
+ ;;
 *)
   targ_obj=UNKNOWN
   ;;