Add a hook in MCELFObjectTargetWriter to allow targets to sort relocation

entries in the relocation table before they are written out to the file. 

llvm-svn: 153345
This commit is contained in:
Akira Hatanaka 2012-03-23 23:06:45 +00:00
parent ef28237798
commit d848fb8bf9
3 changed files with 42 additions and 29 deletions

View File

@ -13,8 +13,35 @@
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ELF.h"
#include <vector>
namespace llvm {
/// @name Relocation Data
/// @{
struct ELFRelocationEntry {
// Make these big enough for both 32-bit and 64-bit
uint64_t r_offset;
int Index;
unsigned Type;
const MCSymbol *Symbol;
uint64_t r_addend;
const MCFixup *Fixup;
ELFRelocationEntry()
: r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0), Fixup(0) {}
ELFRelocationEntry(uint64_t RelocOffset, int Idx, unsigned RelType,
const MCSymbol *Sym, uint64_t Addend, const MCFixup &Fixup)
: r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym),
r_addend(Addend), Fixup(&Fixup) {}
// Support lexicographic sorting.
bool operator<(const ELFRelocationEntry &RE) const {
return RE.r_offset < r_offset;
}
};
class MCELFObjectTargetWriter {
const uint8_t OSABI;
const uint16_t EMachine;
@ -52,6 +79,8 @@ public:
virtual void adjustFixupOffset(const MCFixup &Fixup,
uint64_t &RelocOffset);
virtual void sortRelocs(const MCAssembler &Asm,
std::vector<ELFRelocationEntry> &Relocs);
/// @name Accessors
/// @{

View File

@ -84,32 +84,6 @@ class ELFObjectWriter : public MCObjectWriter {
}
};
/// @name Relocation Data
/// @{
struct ELFRelocationEntry {
// Make these big enough for both 32-bit and 64-bit
uint64_t r_offset;
int Index;
unsigned Type;
const MCSymbol *Symbol;
uint64_t r_addend;
ELFRelocationEntry()
: r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0) {}
ELFRelocationEntry(uint64_t RelocOffset, int Idx,
unsigned RelType, const MCSymbol *Sym,
uint64_t Addend)
: r_offset(RelocOffset), Index(Idx), Type(RelType),
Symbol(Sym), r_addend(Addend) {}
// Support lexicographic sorting.
bool operator<(const ELFRelocationEntry &RE) const {
return RE.r_offset < r_offset;
}
};
/// The target specific ELF writer instance.
llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter;
@ -786,7 +760,7 @@ void ELFObjectWriter::RecordRelocation(const MCAssembler &Asm,
else
assert(isInt<32>(Addend));
ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend);
ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend, Fixup);
Relocations[Fragment->getParent()].push_back(ERE);
}
@ -1072,8 +1046,10 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
MCDataFragment *F,
const MCSectionData *SD) {
std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
// sort by the r_offset just like gnu as does
array_pod_sort(Relocs.begin(), Relocs.end());
// Sort the relocation entries. Most targets just sort by r_offset, but some
// (e.g., MIPS) have additional constraints.
TargetObjectWriter->sortRelocs(Asm, Relocs);
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
ELFRelocationEntry entry = Relocs[e - i - 1];

View File

@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCELFObjectWriter.h"
using namespace llvm;
@ -36,3 +37,10 @@ const MCSymbol *MCELFObjectTargetWriter::ExplicitRelSym(const MCAssembler &Asm,
void MCELFObjectTargetWriter::adjustFixupOffset(const MCFixup &Fixup,
uint64_t &RelocOffset) {
}
void
MCELFObjectTargetWriter::sortRelocs(const MCAssembler &Asm,
std::vector<ELFRelocationEntry> &Relocs) {
// Sort by the r_offset, just like gnu as does.
array_pod_sort(Relocs.begin(), Relocs.end());
}