llvm.org GIT mirror llvm / 4ef61f2
Cleanup relocation sorting for ELF. We want the order to be deterministic on all platforms. NAKAMURA Takumi fixed that in r181864. This patch is just two small cleanups: * Move the function to the cpp file. It is only passed to array_pod_sort. * Remove the ppc implementation which is now redundant git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181910 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 7 years ago
3 changed file(s) with 17 addition(s) and 59 deletion(s). Raw diff Collapse all Expand all
4141 const MCSymbol *Sym, uint64_t Addend, const MCFixup &Fixup)
4242 : r_offset(RelocOffset), Index(Idx), Type(RelType), Symbol(Sym),
4343 r_addend(Addend), Fixup(&Fixup) {}
44
45 // Support lexicographic sorting.
46 bool operator<(const ELFRelocationEntry &RE) const {
47 if (RE.r_offset != r_offset)
48 return RE.r_offset < r_offset;
49 if (Type != RE.Type)
50 return Type < RE.Type;
51 if (Index != RE.Index)
52 return Index < RE.Index;
53 llvm_unreachable("ELFRelocs might be unstable!");
54 return 0;
55 }
5644 };
5745
5846 class MCELFObjectTargetWriter {
3838 return &Symbol.AliasedSymbol();
3939 }
4040
41 // ELF doesn't require relocations to be in any order. We sort by the r_offset,
42 // just to match gnu as for easier comparison. The use type and index is an
43 // arbitrary way of making the sort deterministic.
44 static int cmpRel(const void *AP, const void *BP) {
45 const ELFRelocationEntry &A = *(const ELFRelocationEntry *)AP;
46 const ELFRelocationEntry &B = *(const ELFRelocationEntry *)BP;
47 if (A.r_offset != B.r_offset)
48 return B.r_offset - A.r_offset;
49 if (B.Type != A.Type)
50 return A.Type - B.Type;
51 if (B.Index != A.Index)
52 return B.Index - A.Index;
53 llvm_unreachable("ELFRelocs might be unstable!");
54 }
55
4156 void
4257 MCELFObjectTargetWriter::sortRelocs(const MCAssembler &Asm,
4358 std::vector &Relocs) {
44 // Sort by the r_offset, just like gnu as does.
45 array_pod_sort(Relocs.begin(), Relocs.end());
59 array_pod_sort(Relocs.begin(), Relocs.end(), cmpRel);
4660 }
3232 virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
3333 const MCFixup &Fixup,
3434 bool IsPCRel) const;
35
36 virtual void sortRelocs(const MCAssembler &Asm,
37 std::vector &Relocs);
3835 };
39
40 class PPCELFRelocationEntry : public ELFRelocationEntry {
41 public:
42 PPCELFRelocationEntry(const ELFRelocationEntry &RE);
43 bool operator<(const PPCELFRelocationEntry &RE) const {
44 return (RE.r_offset < r_offset ||
45 (RE.r_offset == r_offset && RE.Type > Type));
46 }
47 };
48 }
49
50 PPCELFRelocationEntry::PPCELFRelocationEntry(const ELFRelocationEntry &RE)
51 : ELFRelocationEntry(RE.r_offset, RE.Index, RE.Type, RE.Symbol,
52 RE.r_addend, *RE.Fixup) {}
36 }
5337
5438 PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
5539 : MCELFObjectTargetWriter(Is64Bit, OSABI,
238222 return NULL;
239223 }
240224
241 // The standard sorter only sorts on the r_offset field, but PowerPC can
242 // have multiple relocations at the same offset. Sort secondarily on the
243 // relocation type to avoid nondeterminism.
244 void PPCELFObjectWriter::sortRelocs(const MCAssembler &Asm,
245 std::vector &Relocs) {
246
247 // Copy to a temporary vector of relocation entries having a different
248 // sort function.
249 std::vector TmpRelocs;
250
251 for (std::vector::iterator R = Relocs.begin();
252 R != Relocs.end(); ++R) {
253 TmpRelocs.push_back(PPCELFRelocationEntry(*R));
254 }
255
256 // Sort in place by ascending r_offset and descending r_type.
257 array_pod_sort(TmpRelocs.begin(), TmpRelocs.end());
258
259 // Copy back to the original vector.
260 unsigned I = 0;
261 for (std::vector::iterator R = TmpRelocs.begin();
262 R != TmpRelocs.end(); ++R, ++I) {
263 Relocs[I] = ELFRelocationEntry(R->r_offset, R->Index, R->Type,
264 R->Symbol, R->r_addend, *R->Fixup);
265 }
266 }
267
268
269225 MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS,
270226 bool Is64Bit,
271227 uint8_t OSABI) {