summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/ELFObjectWriter.cpp
diff options
context:
space:
mode:
authorPetar Jovanovic <petar.jovanovic@imgtec.com>2015-04-14 13:23:34 +0000
committerPetar Jovanovic <petar.jovanovic@imgtec.com>2015-04-14 13:23:34 +0000
commit0380d0b88f8f5101a9b9ec366b769c61e54e1217 (patch)
tree70379c8c9e7bf85694a250e73364167d2b6dc6e0 /llvm/lib/MC/ELFObjectWriter.cpp
parent1dbc317736ce52ce7239d6a1099456e8eac7bcd8 (diff)
downloadbcm5719-llvm-0380d0b88f8f5101a9b9ec366b769c61e54e1217.tar.gz
bcm5719-llvm-0380d0b88f8f5101a9b9ec366b769c61e54e1217.zip
Re-enable target-specific relocation table sorting and use it for Mips
Some targets (ie. Mips) have additional rules for ordering the relocation table entries. Allow them to override generic sortRelocs(), which sorts entries by Offset. Then override this function for Mips, to emit HI16 and GOT16 relocations against the local symbol in pair with the corresponding LO16 relocation. Patch by Vladimir Stefanovic. Differential Revision: http://reviews.llvm.org/D7414 llvm-svn: 234883
Diffstat (limited to 'llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp34
1 files changed, 3 insertions, 31 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp
index cc16ac8fa1e..b2a83993f90 100644
--- a/llvm/lib/MC/ELFObjectWriter.cpp
+++ b/llvm/lib/MC/ELFObjectWriter.cpp
@@ -79,17 +79,6 @@ public:
uint8_t other, uint32_t shndx, bool Reserved);
};
-struct ELFRelocationEntry {
- uint64_t Offset; // Where is the relocation.
- const MCSymbol *Symbol; // The symbol to relocate with.
- unsigned Type; // The type of the relocation.
- uint64_t Addend; // The addend to use.
-
- ELFRelocationEntry(uint64_t Offset, const MCSymbol *Symbol, unsigned Type,
- uint64_t Addend)
- : Offset(Offset), Symbol(Symbol), Type(Type), Addend(Addend) {}
-};
-
class ELFObjectWriter : public MCObjectWriter {
FragmentWriter FWriter;
@@ -1336,31 +1325,14 @@ void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
WriteWord(EntrySize); // sh_entsize
}
-// ELF doesn't require relocations to be in any order. We sort by the r_offset,
-// just to match gnu as for easier comparison. The use type is an arbitrary way
-// of making the sort deterministic.
-static int cmpRel(const ELFRelocationEntry *AP, const ELFRelocationEntry *BP) {
- const ELFRelocationEntry &A = *AP;
- const ELFRelocationEntry &B = *BP;
- if (A.Offset != B.Offset)
- return B.Offset - A.Offset;
- if (B.Type != A.Type)
- return A.Type - B.Type;
- //llvm_unreachable("ELFRelocs might be unstable!");
- return 0;
-}
-
-static void sortRelocs(const MCAssembler &Asm,
- std::vector<ELFRelocationEntry> &Relocs) {
- array_pod_sort(Relocs.begin(), Relocs.end(), cmpRel);
-}
-
void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
MCDataFragment *F,
const MCSectionData *SD) {
std::vector<ELFRelocationEntry> &Relocs = Relocations[SD];
- sortRelocs(Asm, Relocs);
+ // Sort the relocation entries. Most targets just sort by Offset, but some
+ // (e.g., MIPS) have additional constraints.
+ TargetObjectWriter->sortRelocs(Asm, Relocs);
for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
const ELFRelocationEntry &Entry = Relocs[e - i - 1];
OpenPOWER on IntegriCloud