From 00ca888cccd130dd3ebcfc02cf2b9187b54d116e Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 23 Mar 2012 23:06:45 +0000 Subject: [PATCH] Add a hook in MCELFObjectTargetWriter to allow targets to sort relocation entries in the relocation table before they are written out to the file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153345 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCELFObjectWriter.h | 29 ++++++++++++++++++++++++ lib/MC/ELFObjectWriter.cpp | 34 +++++------------------------ 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 6e9f5d81db2..452f8bd28da 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 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 &Relocs); /// @name Accessors /// @{ diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 36f94b4184c..665691770ca 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 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 &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 15bf4767154..171ab4d9bf2 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 &Relocs) { + // Sort by the r_offset, just like gnu as does. + array_pod_sort(Relocs.begin(), Relocs.end()); +}