Add an ELFSymbolRef type.

This allows user code to say Sym.getSize() instead of having to manually fetch
the object.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240708 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2015-06-25 22:10:04 +00:00
parent d26d587fbe
commit b24bbb73a7
5 changed files with 63 additions and 20 deletions

View File

@ -35,10 +35,17 @@
namespace llvm { namespace llvm {
namespace object { namespace object {
class elf_symbol_iterator;
class ELFSymbolRef;
class ELFObjectFileBase : public ObjectFile { class ELFObjectFileBase : public ObjectFile {
friend class ELFSymbolRef;
protected: protected:
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source); ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
public: public:
virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0; virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
@ -46,17 +53,55 @@ public:
// and addend or not. // and addend or not.
virtual bool hasRelocationAddend(DataRefImpl Rel) const = 0; virtual bool hasRelocationAddend(DataRefImpl Rel) const = 0;
virtual symbol_iterator_range getDynamicSymbolIterators() const = 0; typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range;
virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
virtual uint64_t getSectionFlags(SectionRef Sec) const = 0; virtual uint64_t getSectionFlags(SectionRef Sec) const = 0;
virtual uint32_t getSectionType(SectionRef Sec) const = 0; virtual uint32_t getSectionType(SectionRef Sec) const = 0;
virtual uint64_t getSymbolSize(SymbolRef Symb) const = 0; elf_symbol_iterator_range symbols() const;
static inline bool classof(const Binary *v) { return v->isELF(); } static inline bool classof(const Binary *v) { return v->isELF(); }
}; };
class ELFSymbolRef : public SymbolRef {
public:
ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) {
assert(isa<ELFObjectFileBase>(SymbolRef::getObject()));
}
const ELFObjectFileBase *getObject() const {
return cast<ELFObjectFileBase>(BasicSymbolRef::getObject());
}
uint64_t getSize() const {
return getObject()->getSymbolSize(getRawDataRefImpl());
}
};
class elf_symbol_iterator : public symbol_iterator {
public:
elf_symbol_iterator(const basic_symbol_iterator &B)
: symbol_iterator(SymbolRef(B->getRawDataRefImpl(),
cast<ELFObjectFileBase>(B->getObject()))) {}
const ELFSymbolRef *operator->() const {
return static_cast<const ELFSymbolRef *>(symbol_iterator::operator->());
}
const ELFSymbolRef &operator*() const {
return static_cast<const ELFSymbolRef &>(symbol_iterator::operator*());
}
};
inline ELFObjectFileBase::elf_symbol_iterator_range
ELFObjectFileBase::symbols() const {
return elf_symbol_iterator_range(symbol_begin(), symbol_end());
}
template <class ELFT> class ELFObjectFile : public ELFObjectFileBase { template <class ELFT> class ELFObjectFile : public ELFObjectFileBase {
uint64_t getSymbolSize(DataRefImpl Sym) const override;
public: public:
LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) LLVM_ELF_IMPORT_TYPES_ELFT(ELFT)
@ -73,8 +118,6 @@ public:
typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter; typedef typename ELFFile<ELFT>::Elf_Shdr_Iter Elf_Shdr_Iter;
typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter; typedef typename ELFFile<ELFT>::Elf_Dyn_Iter Elf_Dyn_Iter;
uint64_t getSymbolSize(SymbolRef Symb) const override;
protected: protected:
ELFFile<ELFT> EF; ELFFile<ELFT> EF;
@ -206,8 +249,8 @@ public:
basic_symbol_iterator symbol_begin_impl() const override; basic_symbol_iterator symbol_begin_impl() const override;
basic_symbol_iterator symbol_end_impl() const override; basic_symbol_iterator symbol_end_impl() const override;
symbol_iterator dynamic_symbol_begin() const; elf_symbol_iterator dynamic_symbol_begin() const;
symbol_iterator dynamic_symbol_end() const; elf_symbol_iterator dynamic_symbol_end() const;
section_iterator section_begin() const override; section_iterator section_begin() const override;
section_iterator section_end() const override; section_iterator section_end() const override;
@ -236,7 +279,7 @@ public:
ELFT::Is64Bits); ELFT::Is64Bits);
} }
symbol_iterator_range getDynamicSymbolIterators() const override; elf_symbol_iterator_range getDynamicSymbolIterators() const override;
bool isRelocatableObject() const override; bool isRelocatableObject() const override;
}; };
@ -327,8 +370,8 @@ uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const {
} }
template <class ELFT> template <class ELFT>
uint64_t ELFObjectFile<ELFT>::getSymbolSize(SymbolRef Symb) const { uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Sym) const {
return toELFSymIter(Symb.getRawDataRefImpl())->st_size; return toELFSymIter(Sym)->st_size;
} }
template <class ELFT> template <class ELFT>
@ -734,12 +777,12 @@ basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const {
} }
template <class ELFT> template <class ELFT>
symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const { elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this)); return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this));
} }
template <class ELFT> template <class ELFT>
symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const { elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const {
return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this)); return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this));
} }
@ -862,7 +905,7 @@ unsigned ELFObjectFile<ELFT>::getArch() const {
} }
template <class ELFT> template <class ELFT>
ObjectFile::symbol_iterator_range ELFObjectFileBase::elf_symbol_iterator_range
ELFObjectFile<ELFT>::getDynamicSymbolIterators() const { ELFObjectFile<ELFT>::getDynamicSymbolIterators() const {
return make_range(dynamic_symbol_begin(), dynamic_symbol_end()); return make_range(dynamic_symbol_begin(), dynamic_symbol_end());
} }

View File

@ -55,8 +55,8 @@ llvm::object::computeSymbolSizes(const ObjectFile &O) {
auto Syms = E->symbols(); auto Syms = E->symbols();
if (Syms.begin() == Syms.end()) if (Syms.begin() == Syms.end())
Syms = E->getDynamicSymbolIterators(); Syms = E->getDynamicSymbolIterators();
for (SymbolRef Sym : Syms) for (ELFSymbolRef Sym : Syms)
Ret.push_back({Sym, E->getSymbolSize(Sym)}); Ret.push_back({Sym, Sym.getSize()});
return Ret; return Ret;
} }

View File

@ -27,12 +27,12 @@ public:
const MCExpr *createExprForRelocation(RelocationRef Rel) override { const MCExpr *createExprForRelocation(RelocationRef Rel) override {
uint64_t RelType; Rel.getType(RelType); uint64_t RelType; Rel.getType(RelType);
symbol_iterator SymI = Rel.getSymbol(); elf_symbol_iterator SymI = Rel.getSymbol();
StringRef SymName; SymI->getName(SymName); StringRef SymName; SymI->getName(SymName);
uint64_t SymAddr; SymI->getAddress(SymAddr); uint64_t SymAddr; SymI->getAddress(SymAddr);
auto *Obj = cast<ELFObjectFileBase>(Rel.getObjectFile()); auto *Obj = cast<ELFObjectFileBase>(Rel.getObjectFile());
uint64_t SymSize = Obj->getSymbolSize(*SymI); uint64_t SymSize = SymI->getSize();
int64_t Addend = *Obj->getRelocationAddend(Rel.getRawDataRefImpl()); int64_t Addend = *Obj->getRelocationAddend(Rel.getRawDataRefImpl());
MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName); MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName);

View File

@ -930,8 +930,8 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName,
S.Size = 0; S.Size = 0;
S.Address = UnknownAddress; S.Address = UnknownAddress;
if (PrintSize) { if (PrintSize) {
if (auto *E = dyn_cast<ELFObjectFileBase>(&Obj)) if (isa<ELFObjectFileBase>(&Obj))
S.Size = E->getSymbolSize(Sym); S.Size = ELFSymbolRef(Sym).getSize();
} }
if (PrintAddress && isa<ObjectFile>(Obj)) { if (PrintAddress && isa<ObjectFile>(Obj)) {
if (error(SymbolRef(Sym).getAddress(S.Address))) if (error(SymbolRef(Sym).getAddress(S.Address)))

View File

@ -1149,8 +1149,8 @@ void llvm::PrintSymbolTable(const ObjectFile *o) {
outs() << '\t'; outs() << '\t';
if (Common || isa<ELFObjectFileBase>(o)) { if (Common || isa<ELFObjectFileBase>(o)) {
uint64_t Val = Common ? Symbol.getAlignment() uint64_t Val =
: cast<ELFObjectFileBase>(o)->getSymbolSize(Symbol); Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize();
outs() << format("\t %08" PRIx64 " ", Val); outs() << format("\t %08" PRIx64 " ", Val);
} }