class elf_symbol_iterator;
class ELFSymbolRef;
+class ELFRelocationRef;
class ELFObjectFileBase : public ObjectFile {
friend class ELFSymbolRef;
friend class ELFSectionRef;
+ friend class ELFRelocationRef;
protected:
ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
virtual uint32_t getSectionType(DataRefImpl Sec) const = 0;
virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
-public:
virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
-
- // FIXME: This is a bit of a hack. Every caller should know if it expecting
- // and addend or not.
- virtual bool hasRelocationAddend(DataRefImpl Rel) const = 0;
+public:
typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range;
virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
}
};
+class ELFRelocationRef : public RelocationRef {
+public:
+ ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
+ assert(isa<ELFObjectFileBase>(RelocationRef::getObject()));
+ }
+
+ const ELFObjectFileBase *getObject() const {
+ return cast<ELFObjectFileBase>(RelocationRef::getObject());
+ }
+
+ ErrorOr<int64_t> getAddend() const {
+ return getObject()->getRelocationAddend(getRawDataRefImpl());
+ }
+};
+
+class elf_relocation_iterator : public relocation_iterator {
+public:
+ elf_relocation_iterator(const relocation_iterator &B)
+ : relocation_iterator(RelocationRef(
+ B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {}
+
+ const ELFRelocationRef *operator->() const {
+ return static_cast<const ELFRelocationRef *>(
+ relocation_iterator::operator->());
+ }
+
+ const ELFRelocationRef &operator*() const {
+ return static_cast<const ELFRelocationRef &>(
+ relocation_iterator::operator*());
+ }
+};
+
inline ELFObjectFileBase::elf_symbol_iterator_range
ELFObjectFileBase::symbols() const {
return elf_symbol_iterator_range(symbol_begin(), symbol_end());
section_iterator section_end() const override;
ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const override;
- bool hasRelocationAddend(DataRefImpl Rel) const override;
uint8_t getBytesInAddress() const override;
StringRef getFileFormatName() const override;
return (int64_t)getRela(Rel)->r_addend;
}
-template <class ELFT>
-bool ELFObjectFile<ELFT>::hasRelocationAddend(DataRefImpl Rel) const {
- return getRelSection(Rel)->sh_type == ELF::SHT_RELA;
-}
-
template <class ELFT>
const typename ELFFile<ELFT>::Elf_Sym *
ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const {
if (RelSectionName != ".opd")
continue;
- for (relocation_iterator i = si->relocation_begin(),
- e = si->relocation_end();
+ for (elf_relocation_iterator i = si->relocation_begin(),
+ e = si->relocation_end();
i != e;) {
// The R_PPC64_ADDR64 relocation indicates the first field
// of a .opd entry
uint64_t TargetSymbolOffset = i->getOffset();
symbol_iterator TargetSymbol = i->getSymbol();
- ErrorOr<int64_t> AddendOrErr =
- Obj.getRelocationAddend(i->getRawDataRefImpl());
+ ErrorOr<int64_t> AddendOrErr = i->getAddend();
Check(AddendOrErr.getError());
int64_t Addend = *AddendOrErr;
const auto &Obj = cast<ELFObjectFileBase>(O);
uint64_t RelType;
Check(RelI->getType(RelType));
- int64_t Addend = 0;
- if (Obj.hasRelocationAddend(RelI->getRawDataRefImpl()))
- Addend = *Obj.getRelocationAddend(RelI->getRawDataRefImpl());
+ ErrorOr<int64_t> AddendOrErr = ELFRelocationRef(*RelI).getAddend();
+ int64_t Addend = AddendOrErr ? *AddendOrErr : 0;
elf_symbol_iterator Symbol = RelI->getSymbol();
// Obtain the symbol name which is referenced in the relocation