llvm.org GIT mirror llvm / de4d844
Cleanup getRelocationAddend. Realistically, this will be returning ErrorOr for some time as refactoring the user code to check once per section will take some time. Given that, use it for checking if a relocation has addend or not. While at it, add ELFRelocationRef to simplify the users. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241028 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 4 years ago
4 changed file(s) with 42 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
3636
3737 class elf_symbol_iterator;
3838 class ELFSymbolRef;
39 class ELFRelocationRef;
3940
4041 class ELFObjectFileBase : public ObjectFile {
4142 friend class ELFSymbolRef;
4243 friend class ELFSectionRef;
44 friend class ELFRelocationRef;
4345
4446 protected:
4547 ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source);
5153 virtual uint32_t getSectionType(DataRefImpl Sec) const = 0;
5254 virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0;
5355
56 virtual ErrorOr getRelocationAddend(DataRefImpl Rel) const = 0;
5457 public:
55 virtual ErrorOr getRelocationAddend(DataRefImpl Rel) const = 0;
56
57 // FIXME: This is a bit of a hack. Every caller should know if it expecting
58 // and addend or not.
59 virtual bool hasRelocationAddend(DataRefImpl Rel) const = 0;
6058
6159 typedef iterator_range elf_symbol_iterator_range;
6260 virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0;
135133
136134 const ELFSymbolRef &operator*() const {
137135 return static_cast(symbol_iterator::operator*());
136 }
137 };
138
139 class ELFRelocationRef : public RelocationRef {
140 public:
141 ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) {
142 assert(isa(RelocationRef::getObject()));
143 }
144
145 const ELFObjectFileBase *getObject() const {
146 return cast(RelocationRef::getObject());
147 }
148
149 ErrorOr getAddend() const {
150 return getObject()->getRelocationAddend(getRawDataRefImpl());
151 }
152 };
153
154 class elf_relocation_iterator : public relocation_iterator {
155 public:
156 elf_relocation_iterator(const relocation_iterator &B)
157 : relocation_iterator(RelocationRef(
158 B->getRawDataRefImpl(), cast(B->getObject()))) {}
159
160 const ELFRelocationRef *operator->() const {
161 return static_cast(
162 relocation_iterator::operator->());
163 }
164
165 const ELFRelocationRef &operator*() const {
166 return static_cast(
167 relocation_iterator::operator*());
138168 }
139169 };
140170
294324 section_iterator section_end() const override;
295325
296326 ErrorOr getRelocationAddend(DataRefImpl Rel) const override;
297 bool hasRelocationAddend(DataRefImpl Rel) const override;
298327
299328 uint8_t getBytesInAddress() const override;
300329 StringRef getFileFormatName() const override;
730759 if (getRelSection(Rel)->sh_type != ELF::SHT_RELA)
731760 return object_error::parse_failed;
732761 return (int64_t)getRela(Rel)->r_addend;
733 }
734
735 template
736 bool ELFObjectFile::hasRelocationAddend(DataRefImpl Rel) const {
737 return getRelSection(Rel)->sh_type == ELF::SHT_RELA;
738762 }
739763
740764 template
239239 }
240240
241241 int64_t getELFAddend(RelocationRef R) {
242 const auto *Obj = cast(R.getObject());
243 DataRefImpl DRI = R.getRawDataRefImpl();
244 ErrorOr AddendOrErr = Obj->getRelocationAddend(DRI);
242 ErrorOr AddendOrErr = ELFRelocationRef(R).getAddend();
245243 if (std::error_code EC = AddendOrErr.getError())
246244 report_fatal_error(EC.message());
247245 return *AddendOrErr;
766766 if (RelSectionName != ".opd")
767767 continue;
768768
769 for (relocation_iterator i = si->relocation_begin(),
770 e = si->relocation_end();
769 for (elf_relocation_iterator i = si->relocation_begin(),
770 e = si->relocation_end();
771771 i != e;) {
772772 // The R_PPC64_ADDR64 relocation indicates the first field
773773 // of a .opd entry
780780
781781 uint64_t TargetSymbolOffset = i->getOffset();
782782 symbol_iterator TargetSymbol = i->getSymbol();
783 ErrorOr AddendOrErr =
784 Obj.getRelocationAddend(i->getRawDataRefImpl());
783 ErrorOr AddendOrErr = i->getAddend();
785784 Check(AddendOrErr.getError());
786785 int64_t Addend = *AddendOrErr;
787786
10611060 const auto &Obj = cast(O);
10621061 uint64_t RelType;
10631062 Check(RelI->getType(RelType));
1064 int64_t Addend = 0;
1065 if (Obj.hasRelocationAddend(RelI->getRawDataRefImpl()))
1066 Addend = *Obj.getRelocationAddend(RelI->getRawDataRefImpl());
1063 ErrorOr AddendOrErr = ELFRelocationRef(*RelI).getAddend();
1064 int64_t Addend = AddendOrErr ? *AddendOrErr : 0;
10671065 elf_symbol_iterator Symbol = RelI->getSymbol();
10681066
10691067 // Obtain the symbol name which is referenced in the relocation
3030
3131 StringRef SymName; SymI->getName(SymName);
3232 uint64_t SymAddr; SymI->getAddress(SymAddr);
33 auto *Obj = cast(Rel.getObject());
3433 uint64_t SymSize = SymI->getSize();
35 int64_t Addend = *Obj->getRelocationAddend(Rel.getRawDataRefImpl());
34 int64_t Addend = *ELFRelocationRef(Rel).getAddend();
3635
3736 MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName);
3837 // FIXME: check that the value is actually the same.