[llvm-commits] [llvm] r76414 - in /llvm/trunk: include/llvm/Target/TargetELFWriterInfo.h lib/CodeGen/ELFWriter.cpp lib/CodeGen/ELFWriter.h lib/Target/X86/X86ELFWriterInfo.cpp lib/Target/X86/X86ELFWriterInfo.h

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Mon Jul 20 01:52:07 PDT 2009


Author: bruno
Date: Mon Jul 20 03:52:02 2009
New Revision: 76414

URL: http://llvm.org/viewvc/llvm-project?rev=76414&view=rev
Log:
For PC relative relocations where symbols are defined in the same section they
are referenced, ignore the relocation entry and patch the relocatable field with
the computed symbol offset directly

Modified:
    llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h
    llvm/trunk/lib/CodeGen/ELFWriter.cpp
    llvm/trunk/lib/CodeGen/ELFWriter.h
    llvm/trunk/lib/Target/X86/X86ELFWriterInfo.cpp
    llvm/trunk/lib/Target/X86/X86ELFWriterInfo.h

Modified: llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h?rev=76414&r1=76413&r2=76414&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h Mon Jul 20 03:52:02 2009
@@ -105,16 +105,25 @@
     /// ELF relocation entry.
     virtual bool hasRelocationAddend() const = 0;
 
-    /// getAddendForRelTy - Gets the addend value for an ELF relocation entry
-    /// based on the target relocation type. If addend is not used returns 0.
+    /// getDefaultAddendForRelTy - Gets the default addend value for a
+    /// relocation entry based on the target ELF relocation type.
     virtual long int getDefaultAddendForRelTy(unsigned RelTy) const = 0;
 
     /// getRelTySize - Returns the size of relocatable field in bits
     virtual unsigned getRelocationTySize(unsigned RelTy) const = 0;
 
+    /// isPCRelativeRel - True if the relocation type is pc relative
+    virtual bool isPCRelativeRel(unsigned RelTy) const = 0;
+
     /// getJumpTableRelocationTy - Returns the machine relocation type used
     /// to reference a jumptable.
     virtual unsigned getAbsoluteLabelMachineRelTy() const = 0;
+
+    /// computeRelocation - Some relocatable fields could be relocated
+    /// directly, avoiding the emission of a relocation symbol, compute the
+    /// final relocation value for this symbol.
+    virtual long int computeRelocation(unsigned SymOffset, unsigned RelOffset,
+                                       unsigned RelTy) const = 0;
   };
 
 } // end llvm namespace

Modified: llvm/trunk/lib/CodeGen/ELFWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFWriter.cpp?rev=76414&r1=76413&r2=76414&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/ELFWriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/ELFWriter.cpp Mon Jul 20 03:52:02 2009
@@ -145,7 +145,7 @@
   return false;
 }
 
-/// Get jump table section on the section name returned by TAI
+// Get jump table section on the section name returned by TAI
 ELFSection &ELFWriter::getJumpTableSection() {
   unsigned Align = TM.getTargetData()->getPointerABIAlignment();
   return getSection(TAI->getJumpTableDataSection(),
@@ -153,7 +153,7 @@
                     ELFSection::SHF_ALLOC, Align);
 }
 
-///  Get a constant pool section based on the section name returned by TAI
+// Get a constant pool section based on the section name returned by TAI
 ELFSection &ELFWriter::getConstantPoolSection(MachineConstantPoolEntry &CPE) {
   std::string CstPoolName =
     TAI->SelectSectionForMachineConst(CPE.getType())->getName();
@@ -163,6 +163,19 @@
                     CPE.getAlignment());
 }
 
+// Return the relocation section of section 'S'. 'RelA' is true
+// if the relocation section contains entries with addends.
+ELFSection &ELFWriter::getRelocSection(ELFSection &S) {
+  unsigned SectionHeaderTy = TEW->hasRelocationAddend() ?
+                              ELFSection::SHT_RELA : ELFSection::SHT_REL;
+  std::string RelSName(".rel");
+  if (TEW->hasRelocationAddend())
+    RelSName.append("a");
+  RelSName.append(S.getName());
+
+  return getSection(RelSName, SectionHeaderTy, 0, TEW->getPrefELFAlignment());
+}
+
 // getGlobalELFVisibility - Returns the ELF specific visibility type
 unsigned ELFWriter::getGlobalELFVisibility(const GlobalValue *GV) {
   switch (GV->getVisibility()) {
@@ -474,20 +487,32 @@
   return false;
 }
 
+// RelocateField - Patch relocatable field with 'Offset' in 'BO'
+// using a 'Value' of known 'Size'
+void ELFWriter::RelocateField(BinaryObject &BO, uint32_t Offset,
+                              int64_t Value, unsigned Size) {
+  if (Size == 32)
+    BO.fixWord32(Value, Offset);
+  else if (Size == 64)
+    BO.fixWord64(Value, Offset);
+  else
+    llvm_unreachable("don't know howto patch relocatable field");
+}
+
 /// EmitRelocations - Emit relocations
 void ELFWriter::EmitRelocations() {
 
+  // True if the target uses the relocation entry to hold the addend,
+  // otherwise the addend is written directly to the relocatable field.
+  bool HasRelA = TEW->hasRelocationAddend();
+
   // Create Relocation sections for each section which needs it.
   for (unsigned i=0, e=SectionList.size(); i != e; ++i) {
     ELFSection &S = *SectionList[i];
 
     // This section does not have relocations
     if (!S.hasRelocations()) continue;
-
-    // Get the relocation section for section 'S'
-    bool HasRelA = TEW->hasRelocationAddend();
-    ELFSection &RelSec = getRelocSection(S.getName(), HasRelA,
-                                         TEW->getPrefELFAlignment());
+    ELFSection &RelSec = getRelocSection(S);
 
     // 'Link' - Section hdr idx of the associated symbol table
     // 'Info' - Section hdr idx of the section to which the relocation applies
@@ -502,18 +527,15 @@
          MRE = Relos.end(); MRI != MRE; ++MRI) {
       MachineRelocation &MR = *MRI;
 
-      // Holds the relocatable field address as an offset from the
-      // beginning of the section where it lives
-      unsigned Offset = MR.getMachineCodeOffset();
+      // Relocatable field offset from the section start
+      unsigned RelOffset = MR.getMachineCodeOffset();
 
       // Symbol index in the symbol table
       unsigned SymIdx = 0;
 
-      // Target specific ELF relocation type
+      // Target specific relocation field type and size
       unsigned RelType = TEW->getRelocationType(MR.getRelocationType());
-
-      // Constant addend used to compute the value to be stored
-      // into the relocatable field
+      unsigned RelTySize = TEW->getRelocationTySize(RelType);
       int64_t Addend = 0;
 
       // There are several machine relocations types, and each one of
@@ -533,29 +555,33 @@
       } else {
         // Get the symbol index for the section symbol
         unsigned SectionIdx = MR.getConstantVal();
+        SymIdx = SectionList[SectionIdx]->getSymbolTableIndex();
+        Addend = (uint64_t)MR.getResultPointer();
+
+        // For pc relative relocations where symbols are defined in the same
+        // section they are referenced, ignore the relocation entry and patch
+        // the relocatable field with the symbol offset directly.
+        if (S.SectionIdx == SectionIdx && TEW->isPCRelativeRel(RelType)) {
+          int64_t Value = TEW->computeRelocation(Addend, RelOffset, RelType);
+          RelocateField(S, RelOffset, Value, RelTySize);
+          continue;
+        }
 
         // Handle Jump Table Index relocation
         if ((SectionIdx == getJumpTableSection().SectionIdx) &&
-            TEW->hasCustomJumpTableIndexRelTy())
+            TEW->hasCustomJumpTableIndexRelTy()) {
           RelType = TEW->getJumpTableIndexRelTy();
-
-        SymIdx = SectionList[SectionIdx]->getSymbolTableIndex();
-        Addend = (uint64_t)MR.getResultPointer();
+          RelTySize = TEW->getRelocationTySize(RelType);
+        }
       }
 
       // The target without addend on the relocation symbol must be
       // patched in the relocation place itself to contain the addend
-      if (!HasRelA) {
-        if (TEW->getRelocationTySize(RelType) == 32)
-          S.fixWord32(Addend, Offset);
-        else if (TEW->getRelocationTySize(RelType) == 64)
-          S.fixWord64(Addend, Offset);
-        else
-          llvm_unreachable("don't know howto patch relocatable field");
-      }
+      if (!HasRelA)
+        RelocateField(S, RelOffset, Addend, RelTySize);
 
       // Get the relocation entry and emit to the relocation section
-      ELFRelocation Rel(Offset, SymIdx, RelType, HasRelA, Addend);
+      ELFRelocation Rel(RelOffset, SymIdx, RelType, HasRelA, Addend);
       EmitRelocation(RelSec, Rel, HasRelA);
     }
   }

Modified: llvm/trunk/lib/CodeGen/ELFWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFWriter.h?rev=76414&r1=76413&r2=76414&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/ELFWriter.h (original)
+++ llvm/trunk/lib/CodeGen/ELFWriter.h Mon Jul 20 03:52:02 2009
@@ -171,18 +171,6 @@
                         ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC);
     }
 
-    /// Return the relocation section of section 'S'. 'RelA' is true
-    /// if the relocation section contains entries with addends.
-    ELFSection &getRelocSection(std::string SName, bool RelA, unsigned Align) {
-      std::string RelSName(".rel");
-      unsigned SHdrTy = RelA ? ELFSection::SHT_RELA : ELFSection::SHT_REL;
-
-      if (RelA) RelSName.append("a");
-      RelSName.append(SName);
-
-      return getSection(RelSName, SHdrTy, 0, Align);
-    }
-
     ELFSection &getNonExecStackSection() {
       return getSection(".note.GNU-stack", ELFSection::SHT_PROGBITS, 0, 1);
     }
@@ -215,6 +203,7 @@
 
     ELFSection &getJumpTableSection();
     ELFSection &getConstantPoolSection(MachineConstantPoolEntry &CPE);
+    ELFSection &getRelocSection(ELFSection &S);
 
     // Helpers for obtaining ELF specific info.
     unsigned getGlobalELFBinding(const GlobalValue *GV);
@@ -244,6 +233,8 @@
     void EmitSymbolTable();
     void EmitStringTable();
     void OutputSectionsAndSectionTable();
+    void RelocateField(BinaryObject &BO, uint32_t Offset, int64_t Value,
+                       unsigned Size);
     unsigned SortSymbols();
   };
 }

Modified: llvm/trunk/lib/Target/X86/X86ELFWriterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ELFWriterInfo.cpp?rev=76414&r1=76413&r2=76414&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ELFWriterInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ELFWriterInfo.cpp Mon Jul 20 03:52:02 2009
@@ -103,8 +103,44 @@
   return 0;
 }
 
+bool X86ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const {
+  if (is64Bit) {
+    switch(RelTy) {
+      case R_X86_64_PC32:
+        return true;
+      case R_X86_64_32:
+      case R_X86_64_32S:
+      case R_X86_64_64:
+        return false;
+    default:
+      llvm_unreachable("unknown x86_64 relocation type");
+    }
+  } else {
+    switch(RelTy) {
+      case R_386_PC32:
+        return true;
+      case R_386_32:
+        return false;
+    default:
+      llvm_unreachable("unknown x86 relocation type");
+    }
+  }
+  return 0;
+}
+
 unsigned X86ELFWriterInfo::getAbsoluteLabelMachineRelTy() const {
   return is64Bit ?
     X86::reloc_absolute_dword : X86::reloc_absolute_word;
 }
 
+long int X86ELFWriterInfo::computeRelocation(unsigned SymOffset,
+                                             unsigned RelOffset,
+                                             unsigned RelTy) const {
+
+  if (RelTy == R_X86_64_PC32 || RelTy == R_386_PC32)
+    return SymOffset - (RelOffset + 4);
+  else
+    assert("computeRelocation unknown for this relocation type");
+
+  return 0;
+}

Modified: llvm/trunk/lib/Target/X86/X86ELFWriterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ELFWriterInfo.h?rev=76414&r1=76413&r2=76414&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ELFWriterInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86ELFWriterInfo.h Mon Jul 20 03:52:02 2009
@@ -59,16 +59,25 @@
     /// for a jump table index.
     virtual unsigned getJumpTableIndexRelTy() const { return R_X86_64_32S; }
 
-    /// getAddendForRelTy - Gets the addend value for an ELF relocation entry
-    /// based on the target relocation type
+    /// getDefaultAddendForRelTy - Gets the default addend value for a
+    /// relocation entry based on the target ELF relocation type.
     virtual long int getDefaultAddendForRelTy(unsigned RelTy) const;
 
     /// getRelTySize - Returns the size of relocatable field in bits
     virtual unsigned getRelocationTySize(unsigned RelTy) const;
 
+    /// isPCRelativeRel - True if the relocation type is pc relative
+    virtual bool isPCRelativeRel(unsigned RelTy) const;
+
     /// getJumpTableRelocationTy - Returns the machine relocation type used
     /// to reference a jumptable.
     virtual unsigned getAbsoluteLabelMachineRelTy() const;
+
+    /// computeRelocation - Some relocatable fields could be relocated
+    /// directly, avoiding the relocation symbol emission, compute the
+    /// final relocation value for this symbol.
+    virtual long int computeRelocation(unsigned SymOffset, unsigned RelOffset,
+                                       unsigned RelTy) const;
   };
 
 } // end llvm namespace





More information about the llvm-commits mailing list