Added ARM::mls for armv6t2.
[oota-llvm.git] / lib / CodeGen / ELF.h
index 796bc2c3b2c0765fda5f77b334448417eb589ff9..7e983a4d0512c18dcf11a2e3992e97f5df53c0d9 100644 (file)
 #ifndef CODEGEN_ELF_H
 #define CODEGEN_ELF_H
 
-#include "llvm/GlobalVariable.h"
 #include "llvm/CodeGen/BinaryObject.h"
 #include "llvm/CodeGen/MachineRelocation.h"
 #include "llvm/Support/DataTypes.h"
-#include <cstring>
 
 namespace llvm {
-  class BinaryObject;
+  class GlobalValue;
 
   // Identification Indexes
   enum {
@@ -128,7 +126,13 @@ namespace llvm {
   /// added to logical symbol table for the module.  This is eventually
   /// turned into a real symbol table in the file.
   struct ELFSym {
-    const GlobalValue *GV;    // The global value this corresponds to.
+    // The global value this corresponds to. Global symbols can be on of the 
+    // 3 types : if this symbol has a zero initializer, it is common or should
+    // be placed in bss section otherwise it's a constant.
+    const GlobalValue *GV;
+    bool IsCommon;
+    bool IsBss;
+    bool IsConstant;
 
     // ELF specific fields
     unsigned NameIdx;         // Index in .strtab of name, once emitted.
@@ -138,6 +142,9 @@ namespace llvm {
     uint8_t Other;
     unsigned short SectionIdx;
 
+    // Symbol index into the Symbol table
+    unsigned SymTabIdx;
+
     enum { 
       STB_LOCAL = 0,
       STB_GLOBAL = 1,
@@ -159,35 +166,56 @@ namespace llvm {
       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(0),
-                                    SectionIdx(ELFSection::SHN_UNDEF) {
-      if (!GV)
-        return;
-
-      switch (GV->getVisibility()) {
-      default:
-        assert(0 && "unknown visibility type");
-      case GlobalValue::DefaultVisibility:
-        Other = STV_DEFAULT;
-        break;
-      case GlobalValue::HiddenVisibility:
-        Other = STV_HIDDEN;
-        break;
-      case GlobalValue::ProtectedVisibility:
-        Other = STV_PROTECTED;
-        break;
-      }
-    }
+    ELFSym(const GlobalValue *gv) : GV(gv), IsCommon(false), IsBss(false),
+                                    IsConstant(false), NameIdx(0), Value(0),
+                                    Size(0), Info(0), Other(STV_DEFAULT),
+                                    SectionIdx(ELFSection::SHN_UNDEF),
+                                    SymTabIdx(0) {}
+
+    unsigned getBind() { return (Info >> 4) & 0xf; }
+    unsigned getType() { return Info & 0xf; }
 
-    void SetBind(unsigned X) {
+    void setBind(unsigned X) {
       assert(X == (X & 0xF) && "Bind value out of range!");
       Info = (Info & 0x0F) | (X << 4);
     }
-    void SetType(unsigned X) {
+
+    void setType(unsigned X) {
       assert(X == (X & 0xF) && "Type value out of range!");
       Info = (Info & 0xF0) | X;
     }
+
+    void setVisibility(unsigned V) {
+      assert(V == (V & 0x3) && "Type value out of range!");
+      Other = V;
+    }
+  };
+
+  /// ELFRelocation - This class contains all the information necessary to
+  /// to generate any 32-bit or 64-bit ELF relocation entry.
+  class ELFRelocation {
+    uint64_t r_offset;    // offset in the section of the object this applies to
+    uint32_t r_symidx;    // symbol table index of the symbol to use
+    uint32_t r_type;      // machine specific relocation type
+    int64_t  r_add;       // explicit relocation addend
+    bool     r_rela;      // if true then the addend is part of the entry
+                          // otherwise the addend is at the location specified
+                          // by r_offset
+  public:
+    uint64_t getInfo(bool is64Bit) const {
+      if (is64Bit)
+        return ((uint64_t)r_symidx << 32) + ((uint64_t)r_type & 0xFFFFFFFFL);
+      else
+        return (r_symidx << 8)  + (r_type & 0xFFL);
+    }
+
+    uint64_t getOffset() const { return r_offset; }
+    int64_t getAddend() const { return r_add; }
+
+    ELFRelocation(uint64_t off, uint32_t sym, uint32_t type,
+                  bool rela = true, int64_t addend = 0) :
+      r_offset(off), r_symidx(sym), r_type(type),
+      r_add(addend), r_rela(rela) {}
   };
 
 } // end namespace llvm