Teach ARM/MC/ELF about gcc compatible reloc output to get past odd linkage

failures with relocations.

The code committed is a first cut at compatibility for emitted relocations in
ELF .o.

Why do this? because existing ARM tools like emitting relocs symbols as
explicit relocations, not as section-offset relocs.

Result is that with these changes,
1) relocs are now substantially identical what to gcc outputs.
2) larger apps (including many spec2k tests) compile, cross-link, and pass

Added reminder fixme to tests for future conversion to .s form.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124996 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jason W Kim
2011-02-07 01:11:15 +00:00
parent f009a961ca
commit 953a2a3dee
4 changed files with 265 additions and 3 deletions

View File

@@ -30,6 +30,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ELF.h"
#include "llvm/Target/TargetAsmBackend.h"
#include "llvm/ADT/StringSwitch.h"
#include "../Target/X86/X86FixupKinds.h"
#include "../Target/ARM/ARMFixupKinds.h"
@@ -189,6 +190,14 @@ namespace {
const MCValue &Target,
const MCFragment &F) const;
// For arch-specific emission of explicit reloc symbol
virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
const MCValue &Target,
const MCFragment &F,
bool IsBSS) const {
return NULL;
}
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
bool hasRelocationAddend() const {
return TargetObjectWriter->hasRelocationAddend();
@@ -401,6 +410,11 @@ namespace {
virtual void WriteEFlags();
protected:
virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
const MCValue &Target,
const MCFragment &F,
bool IsBSS) const;
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel, bool IsRelocWithSymbol,
int64_t Addend);
@@ -704,7 +718,7 @@ const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
const SectionKind secKind = Section.getKind();
if (secKind.isBSS())
return NULL;
return ExplicitRelSym(Asm, Target, F, true);
if (secKind.isThreadLocal()) {
if (Renamed)
@@ -733,7 +747,7 @@ const MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm,
return &Symbol;
}
return NULL;
return ExplicitRelSym(Asm, Target, F, false);
}
@@ -1490,6 +1504,34 @@ void ARMELFObjectWriter::WriteEFlags() {
Write32(ELF::EF_ARM_EABIMASK & DefaultEABIVersion);
}
// In ARM, _MergedGlobals and other most symbols get emitted directly.
// I.e. not as an offset to a section symbol.
// This code is a first-cut approximation of what ARM/gcc does.
const MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm,
const MCValue &Target,
const MCFragment &F,
bool IsBSS) const {
const MCSymbol &Symbol = Target.getSymA()->getSymbol();
bool EmitThisSym = false;
if (IsBSS) {
EmitThisSym = StringSwitch<bool>(Symbol.getName())
.Case("_MergedGlobals", true)
.Default(false);
} else {
EmitThisSym = StringSwitch<bool>(Symbol.getName())
.Case("_MergedGlobals", true)
.StartsWith(".L.str", true)
.Default(false);
}
if (EmitThisSym)
return &Symbol;
if (! Symbol.isTemporary())
return &Symbol;
return NULL;
}
unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel,
@@ -1604,7 +1646,7 @@ unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
if (RelocNeedsGOT(Modifier))
NeedsGOT = true;
return Type;
}