diff options
Diffstat (limited to 'lib/CodeGen/ELF.h')
-rw-r--r-- | lib/CodeGen/ELF.h | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/lib/CodeGen/ELF.h b/lib/CodeGen/ELF.h index 796bc2c..28b6be8 100644 --- a/lib/CodeGen/ELF.h +++ b/lib/CodeGen/ELF.h @@ -128,7 +128,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. @@ -159,8 +165,9 @@ 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), + 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) { if (!GV) return; @@ -180,16 +187,47 @@ namespace llvm { } } - void SetBind(unsigned X) { + unsigned getBind() { + return (Info >> 4) & 0xf; + } + + 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; } }; + /// 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 #endif |