diff options
-rw-r--r-- | include/llvm/MC/MCELFObjectWriter.h | 29 | ||||
-rw-r--r-- | lib/MC/ELFObjectWriter.cpp | 34 | ||||
-rw-r--r-- | lib/MC/MCELFObjectTargetWriter.cpp | 8 |
3 files changed, 42 insertions, 29 deletions
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h index 6e9f5d81db..452f8bd28d 100644 --- a/include/llvm/MC/MCELFObjectWriter.h +++ b/include/llvm/MC/MCELFObjectWriter.h @@ -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 /// @{ diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 36f94b4184..665691770c 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -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]; diff --git a/lib/MC/MCELFObjectTargetWriter.cpp b/lib/MC/MCELFObjectTargetWriter.cpp index 15bf476715..171ab4d9bf 100644 --- a/lib/MC/MCELFObjectTargetWriter.cpp +++ b/lib/MC/MCELFObjectTargetWriter.cpp @@ -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()); +} |