[llvm-commits] [llvm] r77232 - in /llvm/trunk/lib/CodeGen: ELF.h ELFCodeEmitter.cpp ELFWriter.cpp ELFWriter.h

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Mon Jul 27 11:54:47 PDT 2009


Author: bruno
Date: Mon Jul 27 13:54:47 2009
New Revision: 77232

URL: http://llvm.org/viewvc/llvm-project?rev=77232&view=rev
Log:
Handle external symbols for ELF and add some static methods to ELFSym

Modified:
    llvm/trunk/lib/CodeGen/ELF.h
    llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp
    llvm/trunk/lib/CodeGen/ELFWriter.cpp
    llvm/trunk/lib/CodeGen/ELFWriter.h

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

==============================================================================
--- llvm/trunk/lib/CodeGen/ELF.h (original)
+++ llvm/trunk/lib/CodeGen/ELF.h Mon Jul 27 13:54:47 2009
@@ -56,9 +56,74 @@
   /// added to logical symbol table for the module.  This is eventually
   /// turned into a real symbol table in the file.
   struct ELFSym {
-    // The global value this symbol matches. This should be null if the symbol
-    // is not a global value.
-    const GlobalValue *GV;
+
+    // ELF symbols are related to llvm ones by being one of the two llvm
+    // types, for the other ones (section, file, func) a null pointer is
+    // assumed.
+    union {
+      const GlobalValue *GV;  // If this is a pointer to a GV
+      const char *Ext;  // If this is a pointer to a named symbol
+    } Source;
+
+    // Describes from which source type this ELF symbol comes from,
+    // they can be GlobalValue, ExternalSymbol or neither.
+    enum {
+      isGV,      // The Source.GV field is valid.
+      isExtSym,  // The Source.ExtSym field is valid.
+      isOther    // Not a GlobalValue or External Symbol
+    };
+    unsigned SourceType;
+
+    bool isGlobalValue() { return SourceType == isGV; }
+    bool isExternalSym() { return SourceType == isExtSym; }
+
+    // getGlobalValue - If this is a global value which originated the
+    // elf symbol, return a reference to it.
+    const GlobalValue *getGlobalValue() {
+      assert(SourceType == isGV && "This is not a global value");
+      return Source.GV;
+    };
+
+    // getExternalSym - If this is an external symbol which originated the
+    // elf symbol, return a reference to it.
+    const char *getExternalSymbol() {
+      assert(SourceType == isExtSym && "This is not an external symbol");
+      return Source.Ext;
+    };
+
+    // getGV - From a global value return a elf symbol to represent it
+    static ELFSym *getGV(const GlobalValue *GV, unsigned Bind,
+                         unsigned Type, unsigned Visibility) {
+      ELFSym *Sym = new ELFSym();
+      Sym->Source.GV = GV;
+      Sym->setBind(Bind);
+      Sym->setType(Type);
+      Sym->setVisibility(Visibility);
+      Sym->SourceType = isGV;
+      return Sym;
+    }
+
+    // getExtSym - Create and return an elf symbol to represent an
+    // external symbol
+    static ELFSym *getExtSym(const char *Ext) {
+      ELFSym *Sym = new ELFSym();
+      Sym->Source.Ext = Ext;
+      Sym->setBind(STB_GLOBAL);
+      Sym->setType(STT_NOTYPE);
+      Sym->setVisibility(STV_DEFAULT);
+      Sym->SourceType = isExtSym;
+      return Sym;
+    }
+
+    // getSectionSym - Returns a elf symbol to represent an elf section
+    static ELFSym *getSectionSym() {
+      ELFSym *Sym = new ELFSym();
+      Sym->setBind(ELFSym::STB_LOCAL);
+      Sym->setType(ELFSym::STT_SECTION);
+      Sym->setVisibility(ELFSym::STV_DEFAULT);
+      Sym->SourceType = isOther;
+      return Sym;
+    }
 
     // ELF specific fields
     unsigned NameIdx;         // Index in .strtab of name, once emitted.
@@ -92,9 +157,9 @@
       STV_PROTECTED = 3 // Visible in other components but not preemptable
     };
 
-    ELFSym(const GlobalValue *gv) : GV(gv), NameIdx(0), Value(0),
-                                    Size(0), Info(0), Other(STV_DEFAULT),
-                                    SectionIdx(0), SymTabIdx(0) {}
+    ELFSym() : SourceType(isOther), NameIdx(0), Value(0),
+               Size(0), Info(0), Other(STV_DEFAULT), SectionIdx(0),
+               SymTabIdx(0) {}
 
     unsigned getBind() const { return (Info >> 4) & 0xf; }
     unsigned getType() const { return Info & 0xf; }

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

==============================================================================
--- llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp (original)
+++ llvm/trunk/lib/CodeGen/ELFCodeEmitter.cpp Mon Jul 27 13:54:47 2009
@@ -69,16 +69,11 @@
 bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
   // Add a symbol to represent the function.
   const Function *F = MF.getFunction();
-  ELFSym *FnSym = new ELFSym(F);
-  FnSym->setType(ELFSym::STT_FUNC);
-  FnSym->setBind(EW.getGlobalELFBinding(F));
-  FnSym->setVisibility(EW.getGlobalELFVisibility(F));
+  ELFSym *FnSym = ELFSym::getGV(F, EW.getGlobalELFBinding(F), ELFSym::STT_FUNC,
+                                EW.getGlobalELFVisibility(F));
   FnSym->SectionIdx = ES->SectionIdx;
   FnSym->Size = ES->getCurrentPCOffset()-FnStartOff;
-
-  // keep track of the emitted function leaving its symbol index as zero
-  // to be patched up later when emitting the symbol table
-  EW.setGlobalSymLookup(F, 0);
+  EW.addGlobalSymbol(F);
 
   // Offset from start of Section
   FnSym->Value = FnStartOff;
@@ -108,7 +103,9 @@
     MachineRelocation &MR = Relocations[i];
     intptr_t Addr;
     if (MR.isGlobalValue()) {
-      EW.PendingGlobals.insert(MR.getGlobalValue());
+      EW.addGlobalSymbol(MR.getGlobalValue());
+    } else if (MR.isExternalSymbol()) {
+      EW.addExternalSymbol(MR.getExternalSymbol());
     } else if (MR.isBasicBlock()) {
       Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
       MR.setConstantVal(ES->SectionIdx);

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

==============================================================================
--- llvm/trunk/lib/CodeGen/ELFWriter.cpp (original)
+++ llvm/trunk/lib/CodeGen/ELFWriter.cpp Mon Jul 27 13:54:47 2009
@@ -144,6 +144,21 @@
   return false;
 }
 
+// addGlobalSymbol - Add a global to be processed and to the
+// global symbol lookup, use a zero index for non private symbols
+// because the table index will be determined later.
+void ELFWriter::addGlobalSymbol(const GlobalValue *GV) {
+  PendingGlobals.insert(GV);
+}
+
+// addExternalSymbol - Add the external to be processed and to the
+// external symbol lookup, use a zero index because the symbol
+// table index will be determined later
+void ELFWriter::addExternalSymbol(const char *External) {
+  PendingExternals.insert(External);
+  ExtSymLookup[External] = 0;
+}
+
 // Get jump table section on the section name returned by TAI
 ELFSection &ELFWriter::getJumpTableSection() {
   unsigned Align = TM.getTargetData()->getPointerABIAlignment();
@@ -169,7 +184,7 @@
     default: Kind = SectionKind::get(SectionKind::MergeableConst,false); break;
     }
   }
-  
+
   return getSection(TAI->getSectionForMergeableConstant(Kind)->getName(),
                     ELFSection::SHT_PROGBITS,
                     ELFSection::SHF_MERGE | ELFSection::SHF_ALLOC,
@@ -278,12 +293,18 @@
   if (GblSymLookup.find(GV) != GblSymLookup.end())
     return;
 
+  // If the global is a function already emited in the text section
+  // just add it to the global symbol lookup with a zero index to be
+  // patched up later.
+  if (isa<Function>(GV) && !GV->isDeclaration()) {
+    GblSymLookup[GV] = 0;
+    return;
+  }
+
   // Handle ELF Bind, Visibility and Type for the current symbol
   unsigned SymBind = getGlobalELFBinding(GV);
-  ELFSym *GblSym = new ELFSym(GV);
-  GblSym->setBind(SymBind);
-  GblSym->setVisibility(getGlobalELFVisibility(GV));
-  GblSym->setType(getGlobalELFType(GV));
+  ELFSym *GblSym = ELFSym::getGV(GV, SymBind, getGlobalELFType(GV),
+                                 getGlobalELFVisibility(GV));
 
   if (isELFUndefSym(GV)) {
     GblSym->SectionIdx = ELFSection::SHN_UNDEF;
@@ -341,16 +362,18 @@
     }
   }
 
-  // Private symbols must never go to the symbol table.
-  unsigned SymIdx = 0;
   if (GV->hasPrivateLinkage()) {
+    // For a private symbols, keep track of the index inside the
+    // private list since it will never go to the symbol table and
+    // won't be patched up later.
     PrivateSyms.push_back(GblSym);
-    SymIdx = PrivateSyms.size()-1;
+    GblSymLookup[GV] = PrivateSyms.size()-1;
   } else {
+    // Non private symbol are left with zero indices until they are patched
+    // up during the symbol table emition (where the indicies are created).
     SymbolList.push_back(GblSym);
+    GblSymLookup[GV] = 0;
   }
-
-  setGlobalSymLookup(GV, SymIdx);
 }
 
 void ELFWriter::EmitGlobalConstantStruct(const ConstantStruct *CVS,
@@ -478,10 +501,15 @@
     EmitGlobal(I);
 
   // Emit all pending globals
-  for (SetVector<GlobalValue*>::const_iterator I = PendingGlobals.begin(),
-       E = PendingGlobals.end(); I != E; ++I)
+  for (PendingGblsIter I = PendingGlobals.begin(), E = PendingGlobals.end();
+       I != E; ++I)
     EmitGlobal(*I);
 
+  // Emit all pending externals
+  for (PendingExtsIter I = PendingExternals.begin(), E = PendingExternals.end();
+       I != E; ++I)
+    SymbolList.push_back(ELFSym::getExtSym(*I));
+
   // Emit non-executable stack note
   if (TAI->getNonexecutableStackDirective())
     getNonExecStackSection();
@@ -489,12 +517,8 @@
   // Emit a symbol for each section created until now, skip null section
   for (unsigned i = 1, e = SectionList.size(); i < e; ++i) {
     ELFSection &ES = *SectionList[i];
-    ELFSym *SectionSym = new ELFSym(0);
+    ELFSym *SectionSym = ELFSym::getSectionSym();
     SectionSym->SectionIdx = ES.SectionIdx;
-    SectionSym->Size = 0;
-    SectionSym->setBind(ELFSym::STB_LOCAL);
-    SectionSym->setType(ELFSym::STT_SECTION);
-    SectionSym->setVisibility(ELFSym::STV_DEFAULT);
     SymbolList.push_back(SectionSym);
     ES.Sym = SymbolList.back();
   }
@@ -589,6 +613,10 @@
         } else {
           Addend = TEW->getDefaultAddendForRelTy(RelType);
         }
+      } else if (MR.isExternalSymbol()) {
+        const char *ExtSym = MR.getExternalSymbol();
+        SymIdx = ExtSymLookup[ExtSym];
+        Addend = TEW->getDefaultAddendForRelTy(RelType);
       } else {
         // Get the symbol index for the section symbol
         unsigned SectionIdx = MR.getConstantVal();
@@ -695,7 +723,10 @@
 
     // Use the name mangler to uniquify the LLVM symbol.
     std::string Name;
-    if (Sym.GV) Name.append(Mang->getMangledName(Sym.GV));
+    if (Sym.isGlobalValue())
+      Name.append(Mang->getMangledName(Sym.getGlobalValue()));
+    else if (Sym.isExternalSym())
+      Name.append(Sym.getExternalSymbol());
 
     if (Name.empty()) {
       Sym.NameIdx = 0;
@@ -755,7 +786,7 @@
   SymTab.EntSize = TEW->getSymTabEntrySize();
 
   // The first entry in the symtab is the null symbol
-  SymbolList.insert(SymbolList.begin(), new ELFSym(0));
+  SymbolList.insert(SymbolList.begin(), new ELFSym());
 
   // Reorder the symbol table with local symbols first!
   unsigned FirstNonLocalSymbol = SortSymbols();
@@ -767,8 +798,11 @@
     // Emit symbol to the symbol table
     EmitSymbol(SymTab, Sym);
 
-    // Record the symbol table index for each global value
-    if (Sym.GV) setGlobalSymLookup(Sym.GV, i);
+    // Record the symbol table index for each symbol
+    if (Sym.isGlobalValue())
+      GblSymLookup[Sym.getGlobalValue()] = i;
+    else if (Sym.isExternalSym())
+      ExtSymLookup[Sym.getExternalSymbol()] = i;
 
     // Keep track on the symbol index into the symbol table
     Sym.SymTabIdx = i;

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

==============================================================================
--- llvm/trunk/lib/CodeGen/ELFWriter.h (original)
+++ llvm/trunk/lib/CodeGen/ELFWriter.h Mon Jul 27 13:54:47 2009
@@ -38,6 +38,8 @@
 
   typedef std::vector<ELFSym*>::iterator ELFSymIter;
   typedef std::vector<ELFSection*>::iterator ELFSectionIter;
+  typedef SetVector<const GlobalValue*>::const_iterator PendingGblsIter;
+  typedef SetVector<const char *>::const_iterator PendingExtsIter;
 
   /// ELFWriter - This class implements the common target-independent code for
   /// writing ELF files.  Targets should derive a class from this to
@@ -108,11 +110,22 @@
     /// the SectionList. Used to quickly gather the Section Index from TAI names
     std::map<std::string, ELFSection*> SectionLookup;
 
+    /// PendingGlobals - Globals not processed as symbols yet.
+    SetVector<const GlobalValue*> PendingGlobals;
+
     /// GblSymLookup - This is a mapping from global value to a symbol 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
+    /// symbol references must be quickly mapped to their indices on the lists.
     std::map<const GlobalValue*, uint32_t> GblSymLookup;
 
+    /// PendingExternals - Externals not processed as symbols yet.
+    SetVector<const char *> PendingExternals;
+
+    /// ExtSymLookup - This is a mapping from externals to a symbol index
+    /// in the symbol table list. This is useful since reloc symbol references
+    /// must be quickly mapped to their symbol table indices.
+    std::map<const char *, uint32_t> ExtSymLookup;
+
     /// SymbolList - This is the list of symbols emitted to the symbol table.
     /// When the SymbolList is finally built, local symbols must be placed in
     /// the beginning while non-locals at the end.
@@ -122,11 +135,6 @@
     /// 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.
-    SetVector<GlobalValue*> PendingGlobals;
-
     // Remove tab from section name prefix. This is necessary becase TAI
     // sometimes return a section name prefixed with elf unused chars. This is
     // a little bit dirty. FIXME: find a better approach, maybe add more
@@ -212,10 +220,15 @@
     unsigned getGlobalELFVisibility(const GlobalValue *GV);
     unsigned getElfSectionFlags(SectionKind Kind);
 
-    // setGlobalSymLookup - Set global value 'GV' with 'Index' in the lookup map
-    void setGlobalSymLookup(const GlobalValue *GV, unsigned Index) {
-      GblSymLookup[GV] = Index;
-    }
+    // addGlobalSymbol - Add a global to be processed and to the
+    // global symbol lookup, use a zero index for non private symbols
+    // because the table index will be determined later.
+    void addGlobalSymbol(const GlobalValue *GV);
+
+    // addExternalSymbol - Add the external to be processed and to the
+    // external symbol lookup, use a zero index because the symbol
+    // table index will be determined later
+    void addExternalSymbol(const char *External);
 
     // As we complete the ELF file, we need to update fields in the ELF header
     // (e.g. the location of the section table).  These members keep track of





More information about the llvm-commits mailing list