#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 {
/// 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.
uint8_t Other;
unsigned short SectionIdx;
+ // Symbol index into the Symbol table
+ unsigned SymTabIdx;
+
enum {
STB_LOCAL = 0,
STB_GLOBAL = 1,
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