Add support for relocations to ObjectFile.

Patch by Danil Malyshev!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139314 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer
2011-09-08 20:52:17 +00:00
parent cbf479df8a
commit 0fcab076f0
5 changed files with 606 additions and 34 deletions

View File

@@ -67,6 +67,12 @@ struct coff_section {
support::ulittle32_t Characteristics;
};
struct coff_relocation {
support::ulittle32_t VirtualAddress;
support::ulittle32_t SymbolTableIndex;
support::ulittle16_t Type;
};
class COFFObjectFile : public ObjectFile {
private:
const coff_file_header *Header;
@@ -81,6 +87,7 @@ private:
const coff_symbol *toSymb(DataRefImpl Symb) const;
const coff_section *toSec(DataRefImpl Sec) const;
const coff_relocation *toRel(DataRefImpl Rel) const;
protected:
virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
@@ -99,12 +106,24 @@ protected:
virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
bool &Result) const;
virtual error_code getRelocationNext(DataRefImpl Rel,
RelocationRef &Res) const;
virtual error_code getRelocationAddress(DataRefImpl Rel,
uint64_t &Res) const;
virtual error_code getRelocationSymbol(DataRefImpl Rel,
SymbolRef &Res) const;
virtual error_code getRelocationType(DataRefImpl Rel,
uint32_t &Res) const;
virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
int64_t &Res) const;
public:
COFFObjectFile(MemoryBuffer *Object, error_code &ec);
virtual symbol_iterator begin_symbols() const;
virtual symbol_iterator end_symbols() const;
virtual section_iterator begin_sections() const;
virtual section_iterator end_sections() const;
virtual relocation_iterator begin_relocations() const;
virtual relocation_iterator end_relocations() const;
virtual uint8_t getBytesInAddress() const;
virtual StringRef getFileFormatName() const;

View File

@@ -39,22 +39,6 @@ static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) {
return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
}
class RelocationRef {
DataRefImpl RelocationPimpl;
const ObjectFile *OwningObject;
public:
RelocationRef() : OwningObject(NULL) {
std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl));
}
RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
bool operator==(const RelocationRef &Other) const;
error_code getNext(RelocationRef &Result);
};
/// SymbolRef - This is a value type class that represents a single symbol in
/// the list of symbols in the object file.
class SymbolRef {
@@ -86,6 +70,29 @@ public:
error_code isInternal(bool &Result) const;
};
/// RelocationRef - This is a value type class that represents a single
/// relocation in the list of relocations in the object file.
class RelocationRef {
DataRefImpl RelocationPimpl;
const ObjectFile *OwningObject;
public:
RelocationRef() : OwningObject(NULL) {
std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl));
}
RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
bool operator==(const RelocationRef &Other) const;
error_code getNext(RelocationRef &Result) const;
error_code getAddress(uint64_t &Result) const;
error_code getSymbol(SymbolRef &Result) const;
error_code getType(uint32_t &Result) const;
error_code getAdditionalInfo(int64_t &Result) const;
};
/// SectionRef - This is a value type class that represents a single section in
/// the list of sections in the object file.
class SectionRef {
@@ -160,6 +167,19 @@ protected:
bool &Result) const = 0;
// Same as above for RelocationRef.
friend class RelocationRef;
virtual error_code getRelocationNext(DataRefImpl Rel,
RelocationRef &Res) const = 0;
virtual error_code getRelocationAddress(DataRefImpl Rel,
uint64_t &Res) const =0;
virtual error_code getRelocationSymbol(DataRefImpl Rel,
SymbolRef &Res) const = 0;
virtual error_code getRelocationType(DataRefImpl Rel,
uint32_t &Res) const = 0;
virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel,
int64_t &Res) const = 0;
public:
template<class content_type>
class content_iterator {
@@ -196,6 +216,7 @@ public:
typedef content_iterator<SymbolRef> symbol_iterator;
typedef content_iterator<SectionRef> section_iterator;
typedef content_iterator<RelocationRef> relocation_iterator;
virtual symbol_iterator begin_symbols() const = 0;
virtual symbol_iterator end_symbols() const = 0;
@@ -203,6 +224,9 @@ public:
virtual section_iterator begin_sections() const = 0;
virtual section_iterator end_sections() const = 0;
virtual relocation_iterator begin_relocations() const = 0;
virtual relocation_iterator end_relocations() const = 0;
/// @brief The number of bytes used to represent an address in this object
/// file format.
virtual uint8_t getBytesInAddress() const = 0;
@@ -302,6 +326,37 @@ inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const {
Result);
}
/// RelocationRef
inline RelocationRef::RelocationRef(DataRefImpl RelocationP,
const ObjectFile *Owner)
: RelocationPimpl(RelocationP)
, OwningObject(Owner) {}
inline bool RelocationRef::operator==(const RelocationRef &Other) const {
return RelocationPimpl == Other.RelocationPimpl;
}
inline error_code RelocationRef::getNext(RelocationRef &Result) const {
return OwningObject->getRelocationNext(RelocationPimpl, Result);
}
inline error_code RelocationRef::getAddress(uint64_t &Result) const {
return OwningObject->getRelocationAddress(RelocationPimpl, Result);
}
inline error_code RelocationRef::getSymbol(SymbolRef &Result) const {
return OwningObject->getRelocationSymbol(RelocationPimpl, Result);
}
inline error_code RelocationRef::getType(uint32_t &Result) const {
return OwningObject->getRelocationType(RelocationPimpl, Result);
}
inline error_code RelocationRef::getAdditionalInfo(int64_t &Result) const {
return OwningObject->getRelocationAdditionalInfo(RelocationPimpl, Result);
}
} // end namespace object
} // end namespace llvm