Add a hook in MCELFObjectTargetWriter to allow targets to sort relocation
authorAkira Hatanaka <ahatanaka@mips.com>
Fri, 23 Mar 2012 23:06:45 +0000 (23:06 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Fri, 23 Mar 2012 23:06:45 +0000 (23:06 +0000)
entries in the relocation table before they are written out to the file.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153345 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCELFObjectWriter.h
lib/MC/ELFObjectWriter.cpp
lib/MC/MCELFObjectTargetWriter.cpp

index 6e9f5d81db2355fdf21575a91f32f803664287c6..452f8bd28daea6db8a7c1c10aa57d57d5f73634f 100644 (file)
 #include "llvm/MC/MCObjectWriter.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/ELF.h"
+#include <vector>
 
 namespace llvm {
+/// @name Relocation Data
+/// @{
+
+struct ELFRelocationEntry {
+  // Make these big enough for both 32-bit and 64-bit
+  uint64_t r_offset;
+  int Index;
+  unsigned Type;
+  const MCSymbol *Symbol;
+  uint64_t r_addend;
+  const MCFixup *Fixup;
+
+  ELFRelocationEntry()
+    : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {}
+
+  ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType,
+                     const MCSymbol *Sym, uint64_t Addend, const MCFixup &Fixup)
+    : r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym),
+      r_addend(Addend), Fixup(&Fixup) {}
+
+  // Support lexicographic sorting.
+  bool operator<(const ELFRelocationEntry &RE) const {
+    return RE.r_offset < r_offset;
+  }
+};
+
 class MCELFObjectTargetWriter {
   const uint8_t OSABI;
   const uint16_t EMachine;
@@ -52,6 +79,8 @@ public:
   virtual void adjustFixupOffset(const MCFixup &Fixup,
                                  uint64_t &RelocOffset);
 
+  virtual void sortRelocs(const MCAssembler &Asm,
+                          std::vector<ELFRelocationEntry> &Relocs);
 
   /// @name Accessors
   /// @{
index 36f94b4184c2d282e3d35425da8652ab2a9cde8c..665691770ca5bff95be81cfdcd6c1e0a455b60e9 100644 (file)
@@ -84,32 +84,6 @@ class ELFObjectWriter : public MCObjectWriter {
       }
     };
 
-    /// @name Relocation Data
-    /// @{
-
-    struct ELFRelocationEntry {
-      // Make these big enough for both 32-bit and 64-bit
-      uint64_t r_offset;
-      int Index;
-      unsigned Type;
-      const MCSymbol *Symbol;
-      uint64_t r_addend;
-
-      ELFRelocationEntry()
-        : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0) {}
-
-      ELFRelocationEntry(uint64_t RelocOffset, int Idx,
-                         unsigned RelType, const MCSymbol *Sym,
-                         uint64_t Addend)
-        : r_offset(RelocOffset), Index(Idx), Type(RelType),
-          Symbol(Sym), r_addend(Addend) {}
-
-      // Support lexicographic sorting.
-      bool operator<(const ELFRelocationEntry &RE) const {
-        return RE.r_offset < r_offset;
-      }
-    };
-
     /// The target specific ELF writer instance.
     llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter;
 
@@ -786,7 +760,7 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
   else
     assert(isInt<32>(Addend));
 
-  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend);
+  ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend, Fixup);
   Relocations[Fragment->getParent()].push_back(ERE);
 }
 
@@ -1072,8 +1046,10 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
                                                MCDataFragment *F,
                                                const MCSectionData *SD) {
   std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
-  // sort by the r_offset just like gnu as does
-  array_pod_sort(Relocs.begin(), Relocs.end());
+
+  // Sort the relocation entries. Most targets just sort by r_offset, but some
+  // (e.g., MIPS) have additional constraints.
+  TargetObjectWriter->sortRelocs(Asm, Relocs);
 
   for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
     ELFRelocationEntry entry = Relocs[e - i - 1];
index 15bf4767154e5182f154ccaae4013de09fbdaee9..171ab4d9bf28464d0913a1d214df5187a8ede7a9 100644 (file)
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/MC/MCELFObjectWriter.h"
 
 using namespace llvm;
@@ -36,3 +37,10 @@ const MCSymbol *MCELFObjectTargetWriter::ExplicitRelSym(const MCAssembler &Asm,
 void MCELFObjectTargetWriter::adjustFixupOffset(const MCFixup &Fixup,
                                                 uint64_t &RelocOffset) {
 }
+
+void
+MCELFObjectTargetWriter::sortRelocs(const MCAssembler &Asm,
+                                    std::vector<ELFRelocationEntry> &Relocs) {
+  // Sort by the r_offset, just like gnu as does.
+  array_pod_sort(Relocs.begin(), Relocs.end());
+}