[llvm-commits] [lld] r165477 - in /lld/trunk: lib/ReaderWriter/ELF/CMakeLists.txt lib/ReaderWriter/ELF/HexagonReference.cpp lib/ReaderWriter/ELF/PPCReference.cpp lib/ReaderWriter/ELF/ReferenceKinds.cpp lib/ReaderWriter/ELF/ReferenceKinds.h lib/ReaderWriter/ELF/WriterELF.cpp test/elf/Inputs/branch-test.hexagon test/elf/Inputs/branch-test.ppc test/elf/Inputs/target-test.hexagon test/elf/Inputs/target-test.ppc test/elf/branch.objtxt test/elf/ppc.objtxt tools/lld-core/lld-core.cpp

Sid Manning sidneym at codeaurora.org
Mon Oct 8 19:20:48 PDT 2012


Author: sidneym
Date: Mon Oct  8 21:20:47 2012
New Revision: 165477

URL: http://llvm.org/viewvc/llvm-project?rev=165477&view=rev
Log:

  * Add relocation reference support for Hexagon and PowerPC.
    - Hexagon has many relocation types, this patch covers just
      a subset, more will be added.
    - PowerPC support was added so that we can verify mixed endian
      environments.
  * Add some basic test cases
  * Update ldd-core to accept -endian flag


Added:
    lld/trunk/lib/ReaderWriter/ELF/HexagonReference.cpp
    lld/trunk/lib/ReaderWriter/ELF/PPCReference.cpp
    lld/trunk/test/elf/Inputs/branch-test.hexagon   (with props)
    lld/trunk/test/elf/Inputs/branch-test.ppc   (with props)
    lld/trunk/test/elf/Inputs/target-test.hexagon   (with props)
    lld/trunk/test/elf/Inputs/target-test.ppc   (with props)
    lld/trunk/test/elf/branch.objtxt
    lld/trunk/test/elf/ppc.objtxt
Modified:
    lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/ELF/ReferenceKinds.cpp
    lld/trunk/lib/ReaderWriter/ELF/ReferenceKinds.h
    lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp
    lld/trunk/tools/lld-core/lld-core.cpp

Modified: lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt?rev=165477&r1=165476&r2=165477&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/CMakeLists.txt Mon Oct  8 21:20:47 2012
@@ -2,5 +2,7 @@
   ReaderELF.cpp
   WriterELF.cpp
   ReferenceKinds.cpp
+  HexagonReference.cpp
+  PPCReference.cpp
   WriterOptionsELF.cpp
   )

Added: lld/trunk/lib/ReaderWriter/ELF/HexagonReference.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/HexagonReference.cpp?rev=165477&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/HexagonReference.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/HexagonReference.cpp Mon Oct  8 21:20:47 2012
@@ -0,0 +1,171 @@
+//===- lib/ReaderWriter/ELF/HexagonReference.cpp ----------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "ReferenceKinds.h"
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ELF.h"
+
+namespace lld {
+namespace elf {
+
+//===----------------------------------------------------------------------===//
+//  KindHandler_hexagon
+//  TODO: more to do here
+//===----------------------------------------------------------------------===//
+
+KindHandler_hexagon::~KindHandler_hexagon() {
+}
+
+/// \brief The following relocation routines are derived from the
+/// Hexagon ABI specification, Section 11.6: Relocation
+/// Symbols used:
+///  A: Added used to compute the value, r_addend
+///  P: Place address of the field being relocated, r_offset
+///  S: Value of the symbol whose index resides in the relocation entry.
+
+namespace hexagon {
+int reloc_NONE(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+  return KindHandler_hexagon::NoError;
+}
+
+/// \brief Word32_B22: 0x01ff3ffe : (S + A - P) >> 2 : Verify
+int reloc_B22_PCREL(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+  int32_t result = (uint32_t)(((S + A) - P)>>2);
+  if ((result < 0x200000) && (result > -0x200000)) {
+    result = ((result<<1) & 0x3ffe) | ((result<<3) & 0x01ff0000);
+    *reinterpret_cast<llvm::support::ulittle32_t *>(location) = result |
+                     *reinterpret_cast<llvm::support::ulittle32_t *>(location);
+    return KindHandler_hexagon::NoError;
+  }
+  return KindHandler_hexagon::Overflow;
+}
+
+/// \brief Word32_B15: 0x00df20fe : (S + A - P) >> 2 : Verify
+int reloc_B15_PCREL(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+  int32_t result = (uint32_t)(((S + A) - P)>>2);
+  if ((result < 0x8000) && (result > -0x8000)) {
+    result = ((result<<1) & 0x20fe) | ((result<<7) & 0x00df0000);
+    *reinterpret_cast<llvm::support::ulittle32_t *>(location) = result |
+                      *reinterpret_cast<llvm::support::ulittle32_t *>(location);
+    return KindHandler_hexagon::NoError;
+  }
+  return KindHandler_hexagon::Overflow;
+}
+
+/// \brief Word32_LO: 0x00c03fff : (S + A) : Truncate
+int reloc_LO16(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+  uint32_t result = (uint32_t)(S + A);
+  result = ((result & 0x3fff) | ((result << 2) & 0x00c00000));
+  *reinterpret_cast<llvm::support::ulittle32_t *>(location) = result |
+                    *reinterpret_cast<llvm::support::ulittle32_t *>(location);
+  return KindHandler_hexagon::NoError;
+}
+
+/// \brief Word32_LO: 0x00c03fff : (S + A) >> 16 : Truncate
+int reloc_HI16(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+  uint32_t result = (uint32_t)((S + A)>>16);
+  result = ((result & 0x3fff) | ((result << 2) & 0x00c00000));
+  *reinterpret_cast<llvm::support::ulittle32_t *>(location) = result |
+                    *reinterpret_cast<llvm::support::ulittle32_t *>(location);
+  return KindHandler_hexagon::NoError;
+}
+
+/// \brief Word32: 0xffffffff : (S + A) : Truncate
+int reloc_32(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+  uint32_t result = (uint32_t)(S + A);
+  *reinterpret_cast<llvm::support::ulittle32_t *>(location) = result |
+                    *reinterpret_cast<llvm::support::ulittle32_t *>(location);
+  return KindHandler_hexagon::NoError;
+}
+} // namespace hexagon
+
+KindHandler_hexagon::KindHandler_hexagon(){
+  _fixupHandler[llvm::ELF::R_HEX_B22_PCREL] = hexagon::reloc_B22_PCREL;
+  _fixupHandler[llvm::ELF::R_HEX_B15_PCREL] = hexagon::reloc_B15_PCREL;
+  _fixupHandler[llvm::ELF::R_HEX_LO16]      = hexagon::reloc_LO16;
+  _fixupHandler[llvm::ELF::R_HEX_HI16]      = hexagon::reloc_HI16;
+  _fixupHandler[llvm::ELF::R_HEX_32]        = hexagon::reloc_32;
+}
+
+Reference::Kind KindHandler_hexagon::stringToKind(StringRef str) {
+  return llvm::StringSwitch<Reference::Kind>(str)
+    .Case("none",                  none)
+    .Case("R_HEX_B22_PCREL", llvm::ELF::R_HEX_B22_PCREL)
+    .Case("R_HEX_B15_PCREL", llvm::ELF::R_HEX_B15_PCREL)
+    .Case("R_HEX_LO16",      llvm::ELF::R_HEX_LO16)
+    .Case("R_HEX_HI16",      llvm::ELF::R_HEX_HI16)
+    .Case("R_HEX_32",        llvm::ELF::R_HEX_32)
+    .Default(invalid);
+}
+
+StringRef KindHandler_hexagon::kindToString(Reference::Kind kind) {
+  switch (static_cast<int32_t>(kind)) {
+  case llvm::ELF::R_HEX_B22_PCREL:
+    return "R_HEX_B22_PCREL";
+  case llvm::ELF::R_HEX_B15_PCREL:
+    return "R_HEX_B15_PCREL";
+  case llvm::ELF::R_HEX_LO16:
+    return "R_HEX_LO16";
+  case llvm::ELF::R_HEX_HI16:
+    return "R_HEX_HI16";
+  case llvm::ELF::R_HEX_32:
+    return "R_HEX_32";
+  default:
+    return "none";
+  }
+}
+
+bool KindHandler_hexagon::isCallSite(Kind kind) {
+  llvm_unreachable("Unimplemented: KindHandler_hexagon::isCallSite");
+  return false;
+}
+
+bool KindHandler_hexagon::isPointer(Kind kind) {
+  llvm_unreachable("Unimplemented: KindHandler_hexagon::isPointer");
+  return false;
+}
+
+bool KindHandler_hexagon::isLazyImmediate(Kind kind) {
+  llvm_unreachable("Unimplemented: KindHandler_hexagon::isLazyImmediate");
+  return false;
+}
+
+bool KindHandler_hexagon::isLazyTarget(Kind kind) {
+  llvm_unreachable("Unimplemented: KindHandler_hexagon::isLazyTarget");
+  return false;
+}
+
+void KindHandler_hexagon::applyFixup(int32_t reloc, uint64_t addend,
+                                     uint8_t *location, uint64_t fixupAddress,
+                                     uint64_t targetAddress) {
+  int error;
+  if (_fixupHandler[reloc])
+  {
+    error = (*_fixupHandler[reloc])(location,
+                                    fixupAddress, targetAddress, addend);
+
+    switch ((RelocationError)error) {
+    case NoError:
+      return;
+    case Overflow:
+      llvm::report_fatal_error("applyFixup relocation overflow");
+      return;
+    }
+  }
+}
+
+
+} // namespace elf
+} // namespace lld

Added: lld/trunk/lib/ReaderWriter/ELF/PPCReference.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPCReference.cpp?rev=165477&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPCReference.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/PPCReference.cpp Mon Oct  8 21:20:47 2012
@@ -0,0 +1,116 @@
+//===- lib/ReaderWriter/ELF/PPCReference.cpp ----------------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "ReferenceKinds.h"
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ELF.h"
+
+namespace lld {
+namespace elf {
+
+//===----------------------------------------------------------------------===//
+//  KindHandler_ppc
+//  TODO: more to do here
+//===----------------------------------------------------------------------===//
+
+KindHandler_ppc::~KindHandler_ppc() {
+}
+
+/// \brief The following relocation routines are derived from the
+///  SYSTEM V APPLICATION BINARY INTERFACE: PowerPC Processor Supplement
+/// Symbols used:
+///  A: Added used to compute the value, r_addend
+///  P: Place address of the field being relocated, r_offset
+///  S: Value of the symbol whose index resides in the relocation entry.
+
+namespace ppc {
+int reloc_NONE(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+  return KindHandler_ppc::NoError;
+}
+
+/// \brief low24 (S + A - P) >> 2 : Verify
+int reloc_B24_PCREL(uint8_t *location, uint64_t P, uint64_t S, uint64_t A) {
+  int32_t result = (uint32_t)(((S + A) - P));
+  if ((result < 0x1000000) && (result > -0x1000000)) {
+    result &= ~-(0x1000000);
+    *reinterpret_cast<llvm::support::ubig32_t *>(location) = result |
+                      *reinterpret_cast<llvm::support::ubig32_t *>(location);
+    return KindHandler_ppc::NoError;
+  }
+  return KindHandler_ppc::Overflow;
+}
+} // namespace ppc
+
+KindHandler_ppc::KindHandler_ppc(llvm::support::endianness endian){
+  _fixupHandler[llvm::ELF::R_PPC_REL24] = ppc::reloc_B24_PCREL;
+}
+
+Reference::Kind KindHandler_ppc::stringToKind(StringRef str) {
+  return llvm::StringSwitch<Reference::Kind>(str)
+    .Case("none",                  none)
+    .Case("R_PPC_REL24", llvm::ELF::R_PPC_REL24)
+    .Default(invalid);
+}
+
+StringRef KindHandler_ppc::kindToString(Reference::Kind kind) {
+  switch ((int32_t)kind) {
+  case llvm::ELF::R_PPC_REL24:
+    return "R_PPC_REL24";
+  default:
+    return "none";
+  }
+}
+
+bool KindHandler_ppc::isCallSite(Kind kind) {
+  llvm_unreachable("Unimplemented: KindHandler_ppc::isCallSite");
+  return false;
+}
+
+bool KindHandler_ppc::isPointer(Kind kind) {
+  llvm_unreachable("Unimplemented: KindHandler_ppc::isPointer");
+  return false;
+}
+
+bool KindHandler_ppc::isLazyImmediate(Kind kind) {
+  llvm_unreachable("Unimplemented: KindHandler_ppc::isLazyImmediate");
+  return false;
+}
+
+bool KindHandler_ppc::isLazyTarget(Kind kind) {
+  llvm_unreachable("Unimplemented: KindHandler_ppc::isLazyTarget");
+  return false;
+}
+
+void KindHandler_ppc::applyFixup(int32_t reloc, uint64_t addend,
+                                 uint8_t *location, uint64_t fixupAddress,
+                                 uint64_t targetAddress) {
+  int error;
+  if (_fixupHandler[reloc])
+  {
+    error = (*_fixupHandler[reloc])(location,
+                                    fixupAddress, targetAddress, addend);
+
+    switch ((RelocationError)error) {
+    case NoError:
+      return;
+    case Overflow:
+      llvm::report_fatal_error("applyFixup relocation overflow");
+      return;
+    }
+  }
+}
+
+} // namespace elf
+} // namespace lld

Modified: lld/trunk/lib/ReaderWriter/ELF/ReferenceKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ReferenceKinds.cpp?rev=165477&r1=165476&r2=165477&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ReferenceKinds.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ReferenceKinds.cpp Mon Oct  8 21:20:47 2012
@@ -28,12 +28,15 @@
 KindHandler::~KindHandler() {
 }
 
-std::unique_ptr<KindHandler> KindHandler::makeHandler(uint16_t arch) {
+std::unique_ptr<KindHandler> KindHandler::makeHandler(uint16_t arch,
+                                          llvm::support::endianness endian) {
   switch(arch) {
   case llvm::ELF::EM_HEXAGON:
     return std::unique_ptr<KindHandler>(new KindHandler_hexagon());
   case llvm::ELF::EM_386:
     return std::unique_ptr<KindHandler>(new KindHandler_x86());
+  case llvm::ELF::EM_PPC:
+    return std::unique_ptr<KindHandler>(new KindHandler_ppc(endian));
   default:
     llvm_unreachable("arch not supported");
   }
@@ -55,9 +58,9 @@
 StringRef KindHandler_x86::kindToString(Reference::Kind kind) {
   switch ( (Kinds)kind ) {
     case invalid:
-      return StringRef("invalid");
+      return "invalid";
     case none:
-      return StringRef("none");
+      return "none";
   }
   llvm_unreachable("invalid x86 Reference kind");
 }
@@ -82,82 +85,13 @@
   return false;
 }
 
- 
-void KindHandler_x86::applyFixup(Kind kind, uint64_t addend,  
-                                    uint8_t *location, uint64_t fixupAddress, 
-                                    uint64_t targetAddress) {
-  switch ((Kinds)kind) {
-  case none:
-    // do nothing
-    break;
-  case invalid:
-    assert(0 && "invalid Reference Kind");
-    break;
-  }
-}
-
-//===----------------------------------------------------------------------===//
-//  KindHandler_hexagon
-//  TODO: more to do here
-//===----------------------------------------------------------------------===//
-
-KindHandler_hexagon::~KindHandler_hexagon() {
-}
-
-Reference::Kind KindHandler_hexagon::stringToKind(StringRef str) {
-  return llvm::StringSwitch<Reference::Kind>(str)
-    .Case("none",                  none)
-    .Default(invalid);
-
-  llvm_unreachable("invalid hexagon Reference kind");
-}
-
-StringRef KindHandler_hexagon::kindToString(Reference::Kind kind) {
-  switch ( (Kinds)kind ) {
-    case invalid:
-      return StringRef("invalid");
-    case none:
-      return StringRef("none");
-  }
-  llvm_unreachable("invalid hexagon Reference kind");
-}
-
-bool KindHandler_hexagon::isCallSite(Kind kind) {
-  llvm_unreachable("Unimplemented: KindHandler_hexagon::isCallSite");
-  return false;
-}
-
-bool KindHandler_hexagon::isPointer(Kind kind) {
-  llvm_unreachable("Unimplemented: KindHandler_hexagon::isPointer");
-  return false;
-}
- 
-bool KindHandler_hexagon::isLazyImmediate(Kind kind) {
-  llvm_unreachable("Unimplemented: KindHandler_hexagon::isLazyImmediate");
-  return false;
-}
- 
-bool KindHandler_hexagon::isLazyTarget(Kind kind) {
-  llvm_unreachable("Unimplemented: KindHandler_hexagon::isLazyTarget");
-  return false;
-}
-
- 
-void KindHandler_hexagon::applyFixup(Kind kind, uint64_t addend,  
-                                    uint8_t *location, uint64_t fixupAddress, 
+void KindHandler_x86::applyFixup(int32_t reloc, uint64_t addend,
+                                    uint8_t *location, uint64_t fixupAddress,
                                     uint64_t targetAddress) {
-  switch ((Kinds)kind) {
-  case none:
-    // do nothing
-    break;
-  case invalid:
-    llvm_unreachable("invalid Reference Kind");
-    break;
-  }
+// TODO: Add reloc funcs for X86
+  return;
 }
 
-
-
 } // namespace elf
 } // namespace lld
 

Modified: lld/trunk/lib/ReaderWriter/ELF/ReferenceKinds.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ReferenceKinds.h?rev=165477&r1=165476&r2=165477&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ReferenceKinds.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ReferenceKinds.h Mon Oct  8 21:20:47 2012
@@ -7,11 +7,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/DenseMap.h"
 
 #include "lld/Core/LLVM.h"
 #include "lld/Core/Reference.h"
 #include "lld/ReaderWriter/WriterELF.h"
 
+#include <map>
 #include <memory>
 
 #ifndef LLD_READER_WRITER_ELF_REFERENCE_KINDS_H_
@@ -31,7 +33,8 @@
 public:
   typedef Reference::Kind Kind;
   
-  static std::unique_ptr<KindHandler> makeHandler(uint16_t arch);
+  static std::unique_ptr<KindHandler> makeHandler(uint16_t arch,
+                                      llvm::support::endianness endian);
   virtual             ~KindHandler();
   virtual Kind        stringToKind(StringRef str) = 0;
   virtual StringRef   kindToString(Kind) = 0;
@@ -39,8 +42,10 @@
   virtual bool        isPointer(Kind) = 0; 
   virtual bool        isLazyImmediate(Kind) = 0; 
   virtual bool        isLazyTarget(Kind) = 0; 
-  virtual void        applyFixup(Kind kind, uint64_t addend, uint8_t *location, 
-                           uint64_t fixupAddress, uint64_t targetAddress) = 0;
+  virtual void        applyFixup(int32_t reloc, uint64_t addend,
+                                 uint8_t *location,
+                                 uint64_t fixupAddress,
+                                 uint64_t targetAddress) = 0;
   
 protected:
   KindHandler();
@@ -49,20 +54,38 @@
 
 class KindHandler_hexagon : public KindHandler {
 public:
+
+// Note: Reference::Kinds are a another representation of
+// relocation types, using negative values to represent architecture
+// independent reference type.
+// The positive values are the same ones defined in ELF.h and that
+// is what we are using.
   enum Kinds {
-    invalid,         // used to denote an error creating a Reference
-    none,
+    none            = llvm::ELF::R_HEX_NONE,
+    invalid=255,         // used to denote an error creating a Reference
+  };
+
+  enum RelocationError {
+    NoError,
+    Overflow
   };
 
   virtual ~KindHandler_hexagon();
+  KindHandler_hexagon();
   virtual Kind stringToKind(StringRef str);
   virtual StringRef kindToString(Kind);
   virtual bool isCallSite(Kind);
   virtual bool isPointer(Kind); 
   virtual bool isLazyImmediate(Kind); 
   virtual bool isLazyTarget(Kind); 
-  virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location, 
-                  uint64_t fixupAddress, uint64_t targetAddress);
+  virtual void applyFixup(int32_t reloc, uint64_t addend,
+                          uint8_t *location,
+                          uint64_t fixupAddress, uint64_t targetAddress);
+
+private:
+  std::map<int32_t,
+           int (*)(uint8_t *location, uint64_t fixupAddress,
+                   uint64_t targetAddress, uint64_t addend)> _fixupHandler;
 
 };
 
@@ -81,8 +104,45 @@
   virtual bool isPointer(Kind); 
   virtual bool isLazyImmediate(Kind); 
   virtual bool isLazyTarget(Kind); 
-  virtual void applyFixup(Kind kind, uint64_t addend, uint8_t *location, 
-                  uint64_t fixupAddress, uint64_t targetAddress);
+  virtual void applyFixup(int32_t reloc, uint64_t addend, uint8_t *location,
+                          uint64_t fixupAddress, uint64_t targetAddress);
+
+};
+
+class KindHandler_ppc : public KindHandler {
+public:
+
+// Note: Reference::Kinds are a another representation of
+// relocation types, using negative values to represent architecture
+// independent reference type.
+// The positive values are the same ones defined in ELF.h and that
+// is what we are using.
+  enum Kinds {
+    none            = llvm::ELF::R_PPC_NONE,
+    invalid=255,         // used to denote an error creating a Reference
+  };
+
+  enum RelocationError {
+    NoError,
+    Overflow
+  };
+
+  virtual ~KindHandler_ppc();
+  KindHandler_ppc(llvm::support::endianness endian);
+  virtual Kind stringToKind(StringRef str);
+  virtual StringRef kindToString(Kind);
+  virtual bool isCallSite(Kind);
+  virtual bool isPointer(Kind); 
+  virtual bool isLazyImmediate(Kind); 
+  virtual bool isLazyTarget(Kind); 
+  virtual void applyFixup(int32_t reloc, uint64_t addend,
+                          uint8_t *location,
+                          uint64_t fixupAddress, uint64_t targetAddress);
+
+private:
+  std::map<int32_t,
+           int (*)(uint8_t *location, uint64_t fixupAddress,
+                   uint64_t targetAddress, uint64_t addend)> _fixupHandler;
 
 };
 

Modified: lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp?rev=165477&r1=165476&r2=165477&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp Mon Oct  8 21:20:47 2012
@@ -855,7 +855,8 @@
 ELFWriter<target_endianness, is64Bits>
          ::ELFWriter(const WriterOptionsELF &options)
   : _options(options)
-  , _referenceKindHandler(KindHandler::makeHandler(_options.machine()))
+  , _referenceKindHandler(KindHandler::makeHandler(_options.machine(),
+                                                   target_endianness))
 {}
 
 template<support::endianness target_endianness, bool is64Bits>

Added: lld/trunk/test/elf/Inputs/branch-test.hexagon
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/branch-test.hexagon?rev=165477&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lld/trunk/test/elf/Inputs/branch-test.hexagon
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lld/trunk/test/elf/Inputs/branch-test.ppc
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/branch-test.ppc?rev=165477&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lld/trunk/test/elf/Inputs/branch-test.ppc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lld/trunk/test/elf/Inputs/target-test.hexagon
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/target-test.hexagon?rev=165477&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lld/trunk/test/elf/Inputs/target-test.hexagon
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lld/trunk/test/elf/Inputs/target-test.ppc
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/target-test.ppc?rev=165477&view=auto
==============================================================================
Binary file - no diff available.

Propchange: lld/trunk/test/elf/Inputs/target-test.ppc
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: lld/trunk/test/elf/branch.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/branch.objtxt?rev=165477&view=auto
==============================================================================
--- lld/trunk/test/elf/branch.objtxt (added)
+++ lld/trunk/test/elf/branch.objtxt Mon Oct  8 21:20:47 2012
@@ -0,0 +1,34 @@
+RUN: lld-core -reader ELF %p/Inputs/branch-test.hexagon %p/Inputs/target-test.hexagon | FileCheck %s -check-prefix hexagon-yaml
+RUN: lld-core -arch hexagon -reader ELF -writer ELF -o %t1 %p/Inputs/branch-test.hexagon %p/Inputs/target-test.hexagon
+RUN: elf-dump %t1 |  FileCheck -check-prefix=hexagon-elfdump %s 
+
+hexagon-yaml:    - name:              back
+hexagon-yaml:      scope:             global
+hexagon-yaml:      type:              code
+hexagon-yaml:      section-choice:    custom-required
+hexagon-yaml:      section-name:      .text
+hexagon-yaml:      content:           [ 00, C0, 00, 7F, 00, C0, 00, 5A, 00, 00, 00, 00, 
+hexagon-yaml:                           00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 ]
+
+hexagon-yaml:      fixups:
+hexagon-yaml:      - offset:            4
+hexagon-yaml:        target:            target
+
+hexagon-yaml:    - name:              target
+hexagon-yaml:      scope:             global
+hexagon-yaml:      type:              code
+hexagon-yaml:      section-choice:    custom-required
+hexagon-yaml:      section-name:      .text
+hexagon-yaml:      content:           [ 00, C0, 00, 5A ]
+hexagon-yaml:      fixups:
+hexagon-yaml:      - offset:            0
+hexagon-yaml:        target:            back
+
+
+hexagon-elfdump: ('e_indent[EI_CLASS]', 0x01)
+hexagon-elfdump: ('e_indent[EI_DATA]', 0x01)
+hexagon-elfdump: ('e_indent[EI_VERSION]', 0x01)
+hexagon-elfdump: ('e_indent[EI_OSABI]', 0x00)
+hexagon-elfdump: ('e_indent[EI_ABIVERSION]', 0x00)
+hexagon-elfdump: ('e_type', 0x0002)
+hexagon-elfdump: ('e_machine', 0x00a4)

Added: lld/trunk/test/elf/ppc.objtxt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ppc.objtxt?rev=165477&view=auto
==============================================================================
--- lld/trunk/test/elf/ppc.objtxt (added)
+++ lld/trunk/test/elf/ppc.objtxt Mon Oct  8 21:20:47 2012
@@ -0,0 +1,11 @@
+RUN: lld-core -reader ELF -writer ELF -arch ppc -endian big %p/Inputs/branch-test.ppc %p/Inputs/target-test.ppc -o %t1
+RUN: elf-dump %t1 |  FileCheck -check-prefix=ppc-elfdump %s 
+
+ppc-elfdump: ('e_indent[EI_CLASS]', 0x01)
+ppc-elfdump: ('e_indent[EI_DATA]', 0x02)
+ppc-elfdump: ('e_indent[EI_VERSION]', 0x01)
+ppc-elfdump: ('e_indent[EI_OSABI]', 0x00)
+ppc-elfdump: ('e_indent[EI_ABIVERSION]', 0x00)
+ppc-elfdump: ('e_type', 0x0002)
+ppc-elfdump: ('e_machine', 0x0014)
+

Modified: lld/trunk/tools/lld-core/lld-core.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/tools/lld-core/lld-core.cpp?rev=165477&r1=165476&r2=165477&view=diff
==============================================================================
--- lld/trunk/tools/lld-core/lld-core.cpp (original)
+++ lld/trunk/tools/lld-core/lld-core.cpp Mon Oct  8 21:20:47 2012
@@ -25,6 +25,7 @@
 #include "lld/ReaderWriter/WriterYAML.h"
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/ManagedStatic.h"
@@ -117,7 +118,8 @@
 enum ArchChoice {
   i386 = llvm::ELF::EM_386,
   x86_64 = llvm::ELF::EM_X86_64,
-  hexagon = llvm::ELF::EM_HEXAGON
+  hexagon = llvm::ELF::EM_HEXAGON,
+  ppc = llvm::ELF::EM_PPC
 };
 llvm::cl::opt<ArchChoice> 
 archSelected("arch",
@@ -129,6 +131,22 @@
                "x86_64", "output x86_64, EM_X86_64 file"),
     clEnumValN(hexagon, 
                "hexagon", "output Hexagon, EM_HEXAGON file"),
+    clEnumValN(ppc, 
+               "ppc", "output PowerPC, EM_PPC file"),
+    clEnumValEnd));
+
+
+enum endianChoice {
+  little, big
+};
+llvm::cl::opt<endianChoice>
+endianSelected("endian",
+  llvm::cl::desc("Select endianness of ELF output"),
+  llvm::cl::values(
+    clEnumValN(big, "big", 
+               "output big endian format"),
+    clEnumValN(little, "little", 
+               "output little endian format"),
     clEnumValEnd));
     
 
@@ -163,7 +181,10 @@
     cmdLineOutputFilePath.assign("-");
 
   // create writer for final output, default to i386 if none selected
-  WriterOptionsELF writerOptionsELF(false, llvm::support::little,
+  WriterOptionsELF writerOptionsELF(false,
+                                    endianSelected == big
+                                    ? llvm::support::big
+                                    : llvm::support::little,
                                     llvm::ELF::ET_EXEC,
                                     archSelected.getValue() == 0
                                     ? i386





More information about the llvm-commits mailing list