mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
This patch removes some nondeterminism from direct object file output
for TLS dynamic models on 64-bit PowerPC ELF. The default sort routine for relocations only sorts on the r_offset field; but with TLS, there can be two relocations with the same r_offset. For PowerPC, this patch sorts secondarily on descending r_type, which matches the behavior expected by the linker. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170237 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
99cbdde619
commit
d3eb4f46f0
@ -9,6 +9,7 @@
|
||||
|
||||
#include "MCTargetDesc/PPCMCTargetDesc.h"
|
||||
#include "MCTargetDesc/PPCFixupKinds.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/MC/MCELFObjectWriter.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCValue.h"
|
||||
@ -33,9 +34,25 @@ namespace {
|
||||
const MCFixup &Fixup,
|
||||
bool IsPCRel) const;
|
||||
virtual void adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset);
|
||||
|
||||
virtual void sortRelocs(const MCAssembler &Asm,
|
||||
std::vector<ELFRelocationEntry> &Relocs);
|
||||
};
|
||||
|
||||
class PPCELFRelocationEntry : public ELFRelocationEntry {
|
||||
public:
|
||||
PPCELFRelocationEntry(const ELFRelocationEntry &RE);
|
||||
bool operator<(const PPCELFRelocationEntry &RE) const {
|
||||
return (RE.r_offset < r_offset ||
|
||||
(RE.r_offset == r_offset && RE.Type > Type));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
PPCELFRelocationEntry::PPCELFRelocationEntry(const ELFRelocationEntry &RE)
|
||||
: ELFRelocationEntry(RE.r_offset, RE.Index, RE.Type, RE.Symbol,
|
||||
RE.r_addend, *RE.Fixup) {}
|
||||
|
||||
PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
|
||||
: MCELFObjectTargetWriter(Is64Bit, OSABI,
|
||||
Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC,
|
||||
@ -223,6 +240,34 @@ adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) {
|
||||
}
|
||||
}
|
||||
|
||||
// The standard sorter only sorts on the r_offset field, but PowerPC can
|
||||
// have multiple relocations at the same offset. Sort secondarily on the
|
||||
// relocation type to avoid nondeterminism.
|
||||
void PPCELFObjectWriter::sortRelocs(const MCAssembler &Asm,
|
||||
std::vector<ELFRelocationEntry> &Relocs) {
|
||||
|
||||
// Copy to a temporary vector of relocation entries having a different
|
||||
// sort function.
|
||||
std::vector<PPCELFRelocationEntry> TmpRelocs;
|
||||
|
||||
for (std::vector<ELFRelocationEntry>::iterator R = Relocs.begin();
|
||||
R != Relocs.end(); ++R) {
|
||||
TmpRelocs.push_back(PPCELFRelocationEntry(*R));
|
||||
}
|
||||
|
||||
// Sort in place by ascending r_offset and descending r_type.
|
||||
array_pod_sort(TmpRelocs.begin(), TmpRelocs.end());
|
||||
|
||||
// Copy back to the original vector.
|
||||
unsigned I = 0;
|
||||
for (std::vector<PPCELFRelocationEntry>::iterator R = TmpRelocs.begin();
|
||||
R != TmpRelocs.end(); ++R, ++I) {
|
||||
Relocs[I] = ELFRelocationEntry(R->r_offset, R->Index, R->Type,
|
||||
R->Symbol, R->r_addend, *R->Fixup);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS,
|
||||
bool Is64Bit,
|
||||
uint8_t OSABI) {
|
||||
|
@ -4,10 +4,6 @@
|
||||
; Test correct relocation generation for thread-local storage using
|
||||
; the local dynamic model.
|
||||
|
||||
; Relocations 2 and 3 seem to come out in unpredictable order on some
|
||||
; architectures, so restrict this for now.
|
||||
; REQUIRES: ppc64-registered-target
|
||||
|
||||
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user