[llvm-commits] [llvm] r76326 - in /llvm/trunk: include/llvm/Target/TargetELFWriterInfo.h lib/CodeGen/ELF.h lib/CodeGen/ELFCodeEmitter.cpp 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
Sat Jul 18 12:30:50 PDT 2009


Author: bruno
Date: Sat Jul 18 14:30:09 2009
New Revision: 76326

URL: http://llvm.org/viewvc/llvm-project?rev=76326&view=rev
Log:
Add support to properly reference private symbols on relocation entries.
Use proper relocation type to build relocations for JumpTables (rodata
sections).

Modified:
    llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h
    llvm/trunk/lib/CodeGen/ELF.h
    llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp
    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=76326&r1=76325&r2=76326&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetELFWriterInfo.h Sat Jul 18 14:30:09 2009
@@ -99,7 +99,14 @@
 
     /// getAddendForRelTy - Gets the addend value for an ELF relocation entry
     /// based on the target relocation type. If addend is not used returns 0.
-    virtual long int getAddendForRelTy(unsigned RelTy) const = 0;
+    virtual long int getDefaultAddendForRelTy(unsigned RelTy) const = 0;
+
+    /// getRelTySize - Returns the size of relocatable field in bits
+    virtual unsigned getRelocationTySize(unsigned RelTy) const = 0;
+
+    /// getJumpTableRelocationTy - Returns the machine relocation type used
+    /// to reference a jumptable.
+    virtual unsigned getJumpTableMachineRelocationTy() const = 0;
   };
 
 } // end llvm namespace

Modified: llvm/trunk/lib/CodeGen/ELF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELF.h?rev=76326&r1=76325&r2=76326&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/ELF.h (original)
+++ llvm/trunk/lib/CodeGen/ELF.h Sat Jul 18 14:30:09 2009
@@ -184,6 +184,13 @@
     /// Sym - The symbol to represent this section if it has one.
     ELFSym *Sym;
 
+    /// getSymIndex - Returns the symbol table index of the symbol
+    /// representing this section.
+    unsigned getSymbolTableIndex() const {
+      assert(Sym && "section not present in the symbol table");
+      return Sym->SymTabIdx;
+    }
+
     ELFSection(const std::string &name, bool isLittleEndian, bool is64Bit)
       : BinaryObject(name, isLittleEndian, is64Bit), Type(0), Flags(0), Addr(0),
         Offset(0), Size(0), Link(0), Info(0), Align(0), EntSize(0), Sym(0) {}

Modified: llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp?rev=76326&r1=76325&r2=76326&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp (original)
+++ llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp Sat Jul 18 14:30:09 2009
@@ -20,6 +20,7 @@
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
 #include "llvm/CodeGen/MachineRelocation.h"
 #include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetELFWriterInfo.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetAsmInfo.h"
 #include "llvm/Support/Debug.h"
@@ -160,6 +161,7 @@
          "PIC codegen not yet handled for elf jump tables!");
 
   const TargetAsmInfo *TAI = TM.getTargetAsmInfo();
+  const TargetELFWriterInfo *TEW = TM.getELFWriterInfo();
 
   // Get the ELF Section to emit the jump table
   unsigned Align = TM.getTargetData()->getPointerABIAlignment();
@@ -183,9 +185,10 @@
     // Each MBB entry in the Jump table section has a relocation entry
     // against the current text section.
     for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
+      unsigned MachineRelTy = TEW->getJumpTableMachineRelocationTy();
       MachineRelocation MR =
         MachineRelocation::getBB(JTSection.size(),
-                                 MachineRelocation::VANILLA,
+                                 MachineRelTy,
                                  MBBs[mi]);
 
       // Offset of JT 'i' in JT section

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

==============================================================================
--- llvm/trunk/lib/CodeGen/ELFWriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/ELFWriter.cpp Sat Jul 18 14:30:09 2009
@@ -296,8 +296,16 @@
     }
   }
 
-  if (!GV->hasPrivateLinkage())
+  // Private symbols must never go to the symbol table.
+  unsigned SymIdx = 0;
+  if (GV->hasPrivateLinkage()) {
+    PrivateSyms.push_back(GblSym);
+    SymIdx = PrivateSyms.size()-1;
+  } else {
     SymbolList.push_back(GblSym);
+  }
+
+  GblSymLookup[GV] = SymIdx;
 }
 
 void ELFWriter::EmitGlobalConstantStruct(const ConstantStruct *CVS,
@@ -394,20 +402,16 @@
   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
        I != E; ++I) {
     EmitGlobal(I);
-    GblSymLookup[I] = 0;
   }
 
   // Emit all pending globals
   // TODO: this should be done only for referenced symbols
   for (SetVector<GlobalValue*>::const_iterator I = PendingGlobals.begin(),
        E = PendingGlobals.end(); I != E; ++I) {
-
     // No need to emit the symbol again
     if (GblSymLookup.find(*I) != GblSymLookup.end())
       continue;
-
     EmitGlobal(*I);
-    GblSymLookup[*I] = 0;
   }
 
   // Emit non-executable stack note
@@ -480,7 +484,8 @@
          MRE = Relos.end(); MRI != MRE; ++MRI) {
       MachineRelocation &MR = *MRI;
 
-      // Offset from the start of the section containing the symbol
+      // Holds the relocatable field address as an offset from the
+      // beginning of the section where it lives
       unsigned Offset = MR.getMachineCodeOffset();
 
       // Symbol index in the symbol table
@@ -498,15 +503,34 @@
       if (MR.isGlobalValue()) {
         const GlobalValue *G = MR.getGlobalValue();
         SymIdx = GblSymLookup[G];
-        Addend = TEW->getAddendForRelTy(RelType);
+        if (G->hasPrivateLinkage()) {
+          // If the target uses a section offset in the relocation:
+          // SymIdx + Addend = section sym for global + section offset
+          unsigned SectionIdx = PrivateSyms[SymIdx]->SectionIdx;
+          Addend = PrivateSyms[SymIdx]->Value;
+          SymIdx = SectionList[SectionIdx]->getSymbolTableIndex();
+        } else {
+          Addend = TEW->getDefaultAddendForRelTy(RelType);
+        }
       } else {
         // Get the symbol index for the section symbol referenced
         // by the relocation
         unsigned SectionIdx = MR.getConstantVal();
-        SymIdx = SectionList[SectionIdx]->Sym->SymTabIdx;
+        SymIdx = SectionList[SectionIdx]->getSymbolTableIndex();
         Addend = (uint64_t)MR.getResultPointer();
       }
 
+      // 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");
+      }
+
       // Get the relocation entry and emit to the relocation section
       ELFRelocation Rel(Offset, 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=76326&r1=76325&r2=76326&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/ELFWriter.h (original)
+++ llvm/trunk/lib/CodeGen/ELFWriter.h Sat Jul 18 14:30:09 2009
@@ -107,8 +107,8 @@
     std::map<std::string, ELFSection*> SectionLookup;
 
     /// GblSymLookup - This is a mapping from global value to a symbol index
-    /// in the symbol table. This is useful since relocations symbol references
-    /// must be quickly mapped to a symbol table index
+    /// in the symbol table or private symbols list. This is useful since reloc
+    /// symbol references must be quickly mapped to their indices on the lists
     std::map<const GlobalValue*, uint32_t> GblSymLookup;
 
     /// SymbolList - This is the list of symbols emitted to the symbol table.
@@ -116,6 +116,10 @@
     /// the beginning while non-locals at the end.
     std::vector<ELFSym*> SymbolList;
 
+    /// PrivateSyms - Record private symbols, every symbol here must never be
+    /// present in the SymbolList.
+    std::vector<ELFSym*> PrivateSyms;
+
     /// PendingGlobals - List of externally defined symbols that we have been
     /// asked to emit, but have not seen a reference to.  When a reference
     /// is seen, the symbol will move from this list to the SymbolList.

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

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ELFWriterInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ELFWriterInfo.cpp Sat Jul 18 14:30:09 2009
@@ -43,7 +43,7 @@
       return R_X86_64_64;
     case X86::reloc_picrel_word:
     default:
-      llvm_unreachable("unknown relocation type");
+      llvm_unreachable("unknown x86_64 machine relocation type");
     }
   } else {
     switch(MachineRelTy) {
@@ -54,22 +54,55 @@
     case X86::reloc_absolute_dword:
     case X86::reloc_picrel_word:
     default:
-      llvm_unreachable("unknown relocation type");
+      llvm_unreachable("unknown x86 machine relocation type");
     }
   }
   return 0;
 }
 
-long int X86ELFWriterInfo::getAddendForRelTy(unsigned RelTy) const {
+long int X86ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy) const {
   if (is64Bit) {
     switch(RelTy) {
     case R_X86_64_PC32: return -4;
-      break;
     case R_X86_64_32: return 0;
-      break;
+    default:
+      llvm_unreachable("unknown x86_64 relocation type");
+    }
+  } else {
+    switch(RelTy) {
+      case R_386_PC32: return -4;
+      case R_386_32: return 0;
+    default:
+      llvm_unreachable("unknown x86 relocation type");
+    }
+  }
+  return 0;
+}
+
+unsigned X86ELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
+  if (is64Bit) {
+    switch(RelTy) {
+      case R_X86_64_PC32:
+      case R_X86_64_32:
+        return 32;
+      case R_X86_64_64:
+        return 64;
+    default:
+      llvm_unreachable("unknown x86_64 relocation type");
+    }
+  } else {
+    switch(RelTy) {
+      case R_386_PC32:
+      case R_386_32:
+        return 32;
     default:
       llvm_unreachable("unknown x86 relocation type");
     }
   }
   return 0;
 }
+
+unsigned X86ELFWriterInfo::getJumpTableMachineRelocationTy() const {
+  return X86::reloc_absolute_dword;
+}
+

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

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ELFWriterInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86ELFWriterInfo.h Sat Jul 18 14:30:09 2009
@@ -51,7 +51,14 @@
 
     /// getAddendForRelTy - Gets the addend value for an ELF relocation entry
     /// based on the target relocation type
-    virtual long int getAddendForRelTy(unsigned RelTy) const;
+    virtual long int getDefaultAddendForRelTy(unsigned RelTy) const;
+
+    /// getRelTySize - Returns the size of relocatable field in bits
+    virtual unsigned getRelocationTySize(unsigned RelTy) const;
+
+    /// getJumpTableRelocationTy - Returns the machine relocation type used
+    /// to reference a jumptable.
+    virtual unsigned getJumpTableMachineRelocationTy() const;
   };
 
 } // end llvm namespace





More information about the llvm-commits mailing list